diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,13 @@
+
+# Changelog for ELynx
+
+
+## Version 0.2.1
+
+-   Validation and repetition of previous analyses is finally possible with the
+    new `elynx` binary.
+-   A library `elynx-markov` for running Markov processes along phylogenetic trees
+    has been split off `elynx-seq`. This library performs the computations when
+    executing `slynx simulate ...`.
+-   Many other small improvements.
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://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 <https://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
+<https://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
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,714 @@
+
+
+# The ELynx Suite
+
+Version: 0.2.1.
+Reproducible evolution made easy.
+
+A Haskell library and tool set for computational biology. The goal of ELynx is
+reproducible research. Evolutionary sequences and phylogenetic trees can be
+read, viewed, modified and simulated. The command line with all arguments is
+logged consistently, and automatically. Data integrity is verified using SHA256
+sums so that validation of past analyses is possible without the need to
+recompute the result.
+
+The Elynx Suite consists of four library packages and three executables providing
+a range of sub commands.
+
+The library packages are:
+
+-   **elynx-markov:** Simulate multi sequence alignments along phylogenetic trees.
+-   **elynx-seq:** Handle evolutionary sequences and multi sequence alignments.
+-   **elynx-tools:** Tools for the provided executables.
+-   **elynx-tree:** Handle phylogenetic trees.
+
+The executables are:
+
+-   **slynx:** Analyze, modify, and simulate evolutionary sequences.
+-   **tlynx:** Analyze, modify, and simulate phylogenetic trees.
+-   **elynx:** Validate and redo past analyses.
+
+**ELynx is actively developed. We happily receive comments, ideas, feature
+requests, and pull requests!**
+
+
+# Installation
+
+ELynx is written in [Haskell](https://www.haskell.org/) and can be installed with [Stack](https://docs.haskellstack.org/en/stable/README/).
+
+1.  Install Stack with your package manager, or directly from the web
+    page.
+    
+        curl -sSL https://get.haskellstack.org/ | sh
+
+2.  Clone the ELynx repository.
+    
+        git clone clone https://github.com/dschrempf/elynx
+
+3.  Navigate to the newly created `elynx` folder and build the binaries.
+    This will take a while.
+    
+        stack build
+
+4.  Run a binary from within the project directory. For example,
+    
+        stack exec tlynx -- --help
+
+5.  If needed, install the binaries.
+    
+        stack install
+    
+    The binaries are installed into `~/.local/bin/` which has to be added to the
+    [PATH](https://en.wikipedia.org/wiki/PATH_(variable)) environment variable. Then, they can be used directly.
+
+
+# SLynx
+
+Handle evolutionary sequences.
+
+    slynx --help
+
+    ELynx Suite version 0.2.1.
+    Developed by Dominik Schrempf.
+    Compiled on April 27, 2020, at 06:31 am, UTC.
+    
+    Usage: slynx [-v|--verbosity VALUE] [-o|--output-file-basename NAME] 
+                 [-f|--force] COMMAND
+      Analyze, and simulate multi sequence alignments.
+    
+    Available options:
+      -h,--help                Show this help text
+      -V,--version             Show version
+      -v,--verbosity VALUE     Be verbose; one of: Quiet Warning Info
+                               Debug (default: Info)
+      -o,--output-file-basename NAME
+                               Specify base name of output file
+      -f,--force               Ignore previous analysis and overwrite existing
+                               output files.
+    
+    Available commands:
+      concatenate              Concatenate sequences found in input files.
+      examine                  Examine sequences. If data is a multi sequence alignment, additionally analyze columns.
+      filter-columns           Filter columns of multi sequence alignments.
+      filter-rows              Filter rows (or sequences) found in input files.
+      simulate                 Simulate multi sequence alignments.
+      sub-sample               Sub-sample columns from multi sequence alignments.
+      translate                Translate from DNA to Protein or DNAX to ProteinX.
+    
+    Available sequence file formats:
+      - FASTA
+    
+    Available alphabets:
+      - DNA (nucleotides)
+      - DNAX (nucleotides; including gaps)
+      - DNAI (nucleotides; including gaps, and IUPAC codes)
+      - Protein (amino acids)
+      - ProteinX (amino acids; including gaps)
+      - ProteinS (amino acids; including gaps, and translation stops)
+      - ProteinI (amino acids; including gaps, translation stops, and IUPAC codes)
+    
+    ELynx
+    -----
+    A Haskell library and tool set for computational biology. The goal of ELynx is
+    reproducible research. Evolutionary sequences and phylogenetic trees can be
+    read, viewed, modified and simulated. The command line with all arguments is
+    logged consistently, and automatically. Data integrity is verified using SHA256
+    sums so that validation of past analyses is possible without the need to
+    recompute the result.
+    
+    slynx     Analyze, modify, and simulate evolutionary sequences.
+    tlynx     Analyze, modify, and simulate phylogenetic trees.
+    elynx     Validate and redo past analyses.
+    
+    Get help for sub commands:
+      slynx examine --help
+
+
+## Concatenate
+
+Concatenate multi sequence alignments.
+
+    slynx concatenate --help
+
+    ELynx Suite version 0.2.1.
+    Developed by Dominik Schrempf.
+    Compiled on April 27, 2020, at 06:31 am, UTC.
+    
+    Usage: slynx concatenate (-a|--alphabet NAME) INPUT-FILE
+      Concatenate sequences found in input files.
+    
+    Available options:
+      -h,--help                Show this help text
+      -V,--version             Show version
+      -a,--alphabet NAME       Specify alphabet type NAME
+      INPUT-FILE               Read sequences from INPUT-FILE
+      -h,--help                Show this help text
+    
+    
+    ELynx
+    -----
+    A Haskell library and tool set for computational biology. The goal of ELynx is
+    reproducible research. Evolutionary sequences and phylogenetic trees can be
+    read, viewed, modified and simulated. The command line with all arguments is
+    logged consistently, and automatically. Data integrity is verified using SHA256
+    sums so that validation of past analyses is possible without the need to
+    recompute the result.
+    
+    slynx     Analyze, modify, and simulate evolutionary sequences.
+    tlynx     Analyze, modify, and simulate phylogenetic trees.
+    elynx     Validate and redo past analyses.
+    
+    Get help for sub commands:
+      slynx examine --help
+
+
+## Examine
+
+Examine sequence with `slynx examine`.
+
+    slynx examine --help
+
+    ELynx Suite version 0.2.1.
+    Developed by Dominik Schrempf.
+    Compiled on April 27, 2020, at 06:31 am, UTC.
+    
+    Usage: slynx examine (-a|--alphabet NAME) INPUT-FILE [--per-site]
+      Examine sequences. If data is a multi sequence alignment, additionally analyze columns.
+    
+    Available options:
+      -h,--help                Show this help text
+      -V,--version             Show version
+      -a,--alphabet NAME       Specify alphabet type NAME
+      INPUT-FILE               Read sequences from INPUT-FILE
+      --per-site               Report per site summary statistics
+      -h,--help                Show this help text
+    
+    
+    ELynx
+    -----
+    A Haskell library and tool set for computational biology. The goal of ELynx is
+    reproducible research. Evolutionary sequences and phylogenetic trees can be
+    read, viewed, modified and simulated. The command line with all arguments is
+    logged consistently, and automatically. Data integrity is verified using SHA256
+    sums so that validation of past analyses is possible without the need to
+    recompute the result.
+    
+    slynx     Analyze, modify, and simulate evolutionary sequences.
+    tlynx     Analyze, modify, and simulate phylogenetic trees.
+    elynx     Validate and redo past analyses.
+    
+    Get help for sub commands:
+      slynx examine --help
+
+
+## Filter
+
+Filter sequences with `filer-rows`.
+
+    slynx filter-rows --help
+
+    ELynx Suite version 0.2.1.
+    Developed by Dominik Schrempf.
+    Compiled on April 27, 2020, at 06:31 am, UTC.
+    
+    Usage: slynx filter-rows (-a|--alphabet NAME) INPUT-FILE [--longer-than LENGTH] 
+                             [--shorter-than LENGTH] [--standard-characters]
+      Filter rows (or sequences) found in input files.
+    
+    Available options:
+      -h,--help                Show this help text
+      -V,--version             Show version
+      -a,--alphabet NAME       Specify alphabet type NAME
+      INPUT-FILE               Read sequences from INPUT-FILE
+      --longer-than LENGTH     Only keep sequences longer than LENGTH
+      --shorter-than LENGTH    Only keep sequences shorter than LENGTH
+      --standard-characters    Only keep sequences containing at least one standard
+                               (i.e., non-IUPAC) character
+      -h,--help                Show this help text
+    
+    
+    ELynx
+    -----
+    A Haskell library and tool set for computational biology. The goal of ELynx is
+    reproducible research. Evolutionary sequences and phylogenetic trees can be
+    read, viewed, modified and simulated. The command line with all arguments is
+    logged consistently, and automatically. Data integrity is verified using SHA256
+    sums so that validation of past analyses is possible without the need to
+    recompute the result.
+    
+    slynx     Analyze, modify, and simulate evolutionary sequences.
+    tlynx     Analyze, modify, and simulate phylogenetic trees.
+    elynx     Validate and redo past analyses.
+    
+    Get help for sub commands:
+      slynx examine --help
+
+Filter columns of multi sequence alignments with `filter-columns`.
+
+    slynx filter-columns --help
+
+    ELynx Suite version 0.2.1.
+    Developed by Dominik Schrempf.
+    Compiled on April 27, 2020, at 06:31 am, UTC.
+    
+    Usage: slynx filter-columns (-a|--alphabet NAME) INPUT-FILE 
+                                [--standard-chars DOUBLE]
+      Filter columns of multi sequence alignments.
+    
+    Available options:
+      -h,--help                Show this help text
+      -V,--version             Show version
+      -a,--alphabet NAME       Specify alphabet type NAME
+      INPUT-FILE               Read sequences from INPUT-FILE
+      --standard-chars DOUBLE  Keep columns with a proportion standard (non-IUPAC)
+                               characters larger than DOUBLE in [0,1]
+      -h,--help                Show this help text
+    
+    
+    ELynx
+    -----
+    A Haskell library and tool set for computational biology. The goal of ELynx is
+    reproducible research. Evolutionary sequences and phylogenetic trees can be
+    read, viewed, modified and simulated. The command line with all arguments is
+    logged consistently, and automatically. Data integrity is verified using SHA256
+    sums so that validation of past analyses is possible without the need to
+    recompute the result.
+    
+    slynx     Analyze, modify, and simulate evolutionary sequences.
+    tlynx     Analyze, modify, and simulate phylogenetic trees.
+    elynx     Validate and redo past analyses.
+    
+    Get help for sub commands:
+      slynx examine --help
+
+
+## Simulate
+
+Simulate sequences with `slynx simulate`.
+
+    slynx simulate --help
+
+    ELynx Suite version 0.2.1.
+    Developed by Dominik Schrempf.
+    Compiled on April 27, 2020, at 06:31 am, UTC.
+    
+    Usage: slynx simulate (-t|--tree-file Name) [-s|--substitution-model MODEL] 
+                          [-m|--mixture-model MODEL] [-e|--edm-file NAME] 
+                          [-p|--siteprofile-files NAMES] 
+                          [-w|--mixture-model-weights "[DOUBLE,DOUBLE,...]"] 
+                          [-g|--gamma-rate-heterogeneity "(NCAT,SHAPE)"]
+                          (-l|--length NUMBER) [-S|--seed [INT]]
+      Simulate multi sequence alignments.
+    
+    Available options:
+      -h,--help                Show this help text
+      -V,--version             Show version
+      -t,--tree-file Name      Read tree from Newick file NAME
+      -s,--substitution-model MODEL
+                               Set the phylogenetic substitution model; available
+                               models are shown below (mutually exclusive with -m
+                               option)
+      -m,--mixture-model MODEL Set the phylogenetic mixture model; available models
+                               are shown below (mutually exclusive with -s option)
+      -e,--edm-file NAME       Empirical distribution model file NAME in Phylobayes
+                               format
+      -p,--siteprofile-files NAMES
+                               File names of site profiles in Phylobayes format
+      -w,--mixture-model-weights "[DOUBLE,DOUBLE,...]"
+                               Weights of mixture model components
+      -g,--gamma-rate-heterogeneity "(NCAT,SHAPE)"
+                               Number of gamma rate categories and shape parameter
+      -l,--length NUMBER       Set alignment length to NUMBER
+      -S,--seed [INT]          Seed for random number generator; list of 32 bit
+                               integers with up to 256 elements (default: random)
+      -h,--help                Show this help text
+    
+    Substitution models:
+    -s "MODEL[PARAMETER,PARAMETER,...]{STATIONARY_DISTRIBUTION}"
+       Supported DNA models: JC, F81, HKY, GTR4.
+         For example,
+           -s HKY[KAPPA]{DOUBLE,DOUBLE,DOUBLE,DOUBLE}
+           -s GTR4[e_AC,e_AG,e_AT,e_CG,e_CT,e_GT]{DOUBLE,DOUBLE,DOUBLE,DOUBLE}
+              where the 'e_XY' are the exchangeabilities from nucleotide X to Y.
+       Supported Protein models: Poisson, Poisson-Custom, LG, LG-Custom, WAG, WAG-Custom, GTR20.
+         MODEL-Custom means that only the exchangeabilities of MODEL are used,
+         and a custom stationary distribution is provided.
+         For example,
+           -s LG
+           -s LG-Custom{...}
+           -s GTR20[e_AR,e_AN,...]{...}
+              the 'e_XY' are the exchangeabilities from amino acid X to Y (alphabetical order).
+       Notes: The F81 model for DNA is equivalent to the Poisson-Custom for proteins.
+              The GTR4 model for DNA is equivalent to the GTR20 for proteins.
+    
+    Mixture models:
+    -m "MIXTURE(SUBSTITUTION_MODEL_1,SUBSTITUTION_MODEL_2[PARAMETERS]{STATIONARY_DISTRIBUTION},...)"
+       For example,
+         -m "MIXTURE(JC,HKY[6.0]{0.3,0.2,0.2,0.3})"
+    Mixture weights have to be provided with the -w option.
+    
+    Special mixture models:
+    -m CXX
+       where XX is 10, 20, 30, 40, 50, or 60; CXX models, Quang et al., 2008.
+    -m "EDM(EXCHANGEABILITIES)"
+       Arbitrary empirical distribution mixture (EDM) models.
+       Stationary distributions have to be provided with the -e option.
+       For example,
+         LG exchangeabilities with stationary distributions given in FILE.
+         -m "EDM(LG-Custom)" -e FILE
+    For special mixture models, mixture weights are optional.
+    
+    ELynx
+    -----
+    A Haskell library and tool set for computational biology. The goal of ELynx is
+    reproducible research. Evolutionary sequences and phylogenetic trees can be
+    read, viewed, modified and simulated. The command line with all arguments is
+    logged consistently, and automatically. Data integrity is verified using SHA256
+    sums so that validation of past analyses is possible without the need to
+    recompute the result.
+    
+    slynx     Analyze, modify, and simulate evolutionary sequences.
+    tlynx     Analyze, modify, and simulate phylogenetic trees.
+    elynx     Validate and redo past analyses.
+    
+    Get help for sub commands:
+      slynx examine --help
+
+
+## Sub-sample
+
+Sub-sample columns from multi sequence alignments.
+
+    slynx sub-sample --help
+
+    ELynx Suite version 0.2.1.
+    Developed by Dominik Schrempf.
+    Compiled on April 27, 2020, at 06:31 am, UTC.
+    
+    Usage: slynx sub-sample (-a|--alphabet NAME) INPUT-FILE
+                            (-n|--number-of-sites INT)
+                            (-m|--number-of-alignments INT) [-S|--seed [INT]]
+      Sub-sample columns from multi sequence alignments.
+    
+    Available options:
+      -h,--help                Show this help text
+      -V,--version             Show version
+      -a,--alphabet NAME       Specify alphabet type NAME
+      INPUT-FILE               Read sequences from INPUT-FILE
+      -n,--number-of-sites INT Number of sites randomly drawn with replacement
+      -m,--number-of-alignments INT
+                               Number of multi sequence alignments to be created
+      -S,--seed [INT]          Seed for random number generator; list of 32 bit
+                               integers with up to 256 elements (default: random)
+      -h,--help                Show this help text
+    
+    Create a given number of multi sequence alignments, each of which contains a given number of random sites drawn from the original multi sequence alignment.
+    
+    ELynx
+    -----
+    A Haskell library and tool set for computational biology. The goal of ELynx is
+    reproducible research. Evolutionary sequences and phylogenetic trees can be
+    read, viewed, modified and simulated. The command line with all arguments is
+    logged consistently, and automatically. Data integrity is verified using SHA256
+    sums so that validation of past analyses is possible without the need to
+    recompute the result.
+    
+    slynx     Analyze, modify, and simulate evolutionary sequences.
+    tlynx     Analyze, modify, and simulate phylogenetic trees.
+    elynx     Validate and redo past analyses.
+    
+    Get help for sub commands:
+      slynx examine --help
+
+
+## Translate
+
+Translate sequences.
+
+    slynx translate --help
+
+    ELynx Suite version 0.2.1.
+    Developed by Dominik Schrempf.
+    Compiled on April 27, 2020, at 06:31 am, UTC.
+    
+    Usage: slynx translate (-a|--alphabet NAME) INPUT-FILE (-r|--reading-frame INT)
+                           (-u|--universal-code CODE)
+      Translate from DNA to Protein or DNAX to ProteinX.
+    
+    Available options:
+      -h,--help                Show this help text
+      -V,--version             Show version
+      -a,--alphabet NAME       Specify alphabet type NAME
+      INPUT-FILE               Read sequences from INPUT-FILE
+      -r,--reading-frame INT   Reading frame [0|1|2].
+      -u,--universal-code CODE universal code; one of: Standard,
+                               VertebrateMitochondrial.
+      -h,--help                Show this help text
+    
+    
+    ELynx
+    -----
+    A Haskell library and tool set for computational biology. The goal of ELynx is
+    reproducible research. Evolutionary sequences and phylogenetic trees can be
+    read, viewed, modified and simulated. The command line with all arguments is
+    logged consistently, and automatically. Data integrity is verified using SHA256
+    sums so that validation of past analyses is possible without the need to
+    recompute the result.
+    
+    slynx     Analyze, modify, and simulate evolutionary sequences.
+    tlynx     Analyze, modify, and simulate phylogenetic trees.
+    elynx     Validate and redo past analyses.
+    
+    Get help for sub commands:
+      slynx examine --help
+
+
+# TLynx
+
+Handle phylogenetic trees in Newick format.
+
+    tlynx --help
+
+    ELynx Suite version 0.2.1.
+    Developed by Dominik Schrempf.
+    Compiled on April 27, 2020, at 06:31 am, UTC.
+    
+    Usage: tlynx [-v|--verbosity VALUE] [-o|--output-file-basename NAME] 
+                 [-f|--force] COMMAND
+      Compare, examine, and simulate phylogenetic trees.
+    
+    Available options:
+      -h,--help                Show this help text
+      -V,--version             Show version
+      -v,--verbosity VALUE     Be verbose; one of: Quiet Warning Info
+                               Debug (default: Info)
+      -o,--output-file-basename NAME
+                               Specify base name of output file
+      -f,--force               Ignore previous analysis and overwrite existing
+                               output files.
+    
+    Available commands:
+      coalesce                 Simulate phylogenetic trees using the coalescent processes (see also the 'simulate' command for simulations using the birth and death process).
+      compare                  Compare two phylogenetic trees (compute distances and branch-wise differences).
+      connect                  Connect two phylogenetic trees in all ways (possibly honoring constraints).
+      distance                 Compute distances between many phylogenetic trees.
+      examine                  Compute summary statistics of phylogenetic trees.
+      shuffle                  Shuffle a phylogenetic tree (keep coalescent times, but shuffle topology and leaves).
+      simulate                 Simulate phylogenetic trees using birth and death processes (see also the 'coalesce' command for simulations using the coalescent process).
+    
+    Available tree file formats:
+      - Newick Standard: Branch support values are stored in square brackets after branch lengths.
+      - Newick IqTree:   Branch support values are stored as node names after the closing bracket of forests.
+      - Newick RevBayes  Key-value pairs is provided in square brackets after node names as well as branch lengths. XXX: Key value pairs are IGNORED at the moment.
+    
+    ELynx
+    -----
+    A Haskell library and tool set for computational biology. The goal of ELynx is
+    reproducible research. Evolutionary sequences and phylogenetic trees can be
+    read, viewed, modified and simulated. The command line with all arguments is
+    logged consistently, and automatically. Data integrity is verified using SHA256
+    sums so that validation of past analyses is possible without the need to
+    recompute the result.
+    
+    slynx     Analyze, modify, and simulate evolutionary sequences.
+    tlynx     Analyze, modify, and simulate phylogenetic trees.
+    elynx     Validate and redo past analyses.
+    
+    Get help for sub commands:
+      slynx examine --help
+
+
+## Compare
+
+Compute distances between phylogenetic trees.
+
+    tlynx compare --help
+
+    ELynx Suite version 0.2.1.
+    Developed by Dominik Schrempf.
+    Compiled on April 27, 2020, at 06:31 am, UTC.
+    
+    Usage: tlynx compare [-n|--normalize] [-b|--bipartitions] [-t|--intersect] 
+                         [-f|--newick-format FORMAT] NAME
+      Compare two phylogenetic trees (compute distances and branch-wise differences).
+    
+    Available options:
+      -h,--help                Show this help text
+      -V,--version             Show version
+      -n,--normalize           Normalize trees before comparison
+      -b,--bipartitions        Print and plot common and missing bipartitions
+      -t,--intersect           Compare intersections; i.e., before comparison, drop
+                               leaves that are not present in the other tree
+      -f,--newick-format FORMAT
+                               Newick tree format; see 'tlynx
+                               --help' (default: Standard)
+      NAME                     Tree file
+      -h,--help                Show this help text
+    
+    
+    ELynx
+    -----
+    A Haskell library and tool set for computational biology. The goal of ELynx is
+    reproducible research. Evolutionary sequences and phylogenetic trees can be
+    read, viewed, modified and simulated. The command line with all arguments is
+    logged consistently, and automatically. Data integrity is verified using SHA256
+    sums so that validation of past analyses is possible without the need to
+    recompute the result.
+    
+    slynx     Analyze, modify, and simulate evolutionary sequences.
+    tlynx     Analyze, modify, and simulate phylogenetic trees.
+    elynx     Validate and redo past analyses.
+    
+    Get help for sub commands:
+      slynx examine --help
+
+
+## Examine
+
+Compute summary statistics of phylogenetic trees.
+
+    tlynx examine --help
+
+    ELynx Suite version 0.2.1.
+    Developed by Dominik Schrempf.
+    Compiled on April 27, 2020, at 06:31 am, UTC.
+    
+    Usage: tlynx examine INPUT-FILE [-f|--newick-format FORMAT]
+      Compute summary statistics of phylogenetic trees.
+    
+    Available options:
+      -h,--help                Show this help text
+      -V,--version             Show version
+      INPUT-FILE               Read trees from INPUT-FILE
+      -f,--newick-format FORMAT
+                               Newick tree format; see 'tlynx
+                               --help' (default: Standard)
+      -h,--help                Show this help text
+    
+    
+    ELynx
+    -----
+    A Haskell library and tool set for computational biology. The goal of ELynx is
+    reproducible research. Evolutionary sequences and phylogenetic trees can be
+    read, viewed, modified and simulated. The command line with all arguments is
+    logged consistently, and automatically. Data integrity is verified using SHA256
+    sums so that validation of past analyses is possible without the need to
+    recompute the result.
+    
+    slynx     Analyze, modify, and simulate evolutionary sequences.
+    tlynx     Analyze, modify, and simulate phylogenetic trees.
+    elynx     Validate and redo past analyses.
+    
+    Get help for sub commands:
+      slynx examine --help
+
+
+## Simulate
+
+Simulate phylogenetic trees using birth and death processes.
+
+    tlynx simulate --help
+
+    ELynx Suite version 0.2.1.
+    Developed by Dominik Schrempf.
+    Compiled on April 27, 2020, at 06:31 am, UTC.
+    
+    Usage: tlynx simulate [-t|--nTrees INT] [-n|--nLeaves INT] [-H|--height DOUBLE] 
+                          [-M|--condition-on-mrca] [-l|--lambda DOUBLE] 
+                          [-m|--mu DOUBLE] [-r|--rho DOUBLE] [-u|--sub-sample] 
+                          [-s|--summary-statistics] [-S|--seed [INT]]
+      Simulate phylogenetic trees using birth and death processes (see also the 'coalesce' command for simulations using the coalescent process).
+    
+    Available options:
+      -h,--help                Show this help text
+      -V,--version             Show version
+      -t,--nTrees INT          Number of trees (default: 10)
+      -n,--nLeaves INT         Number of leaves per tree (default: 5)
+      -H,--height DOUBLE       Fix tree height (no default)
+      -M,--condition-on-mrca   Do not condition on height of origin but on height of
+                               MRCA
+      -l,--lambda DOUBLE       Birth rate lambda (default: 1.0)
+      -m,--mu DOUBLE           Death rate mu (default: 0.9)
+      -r,--rho DOUBLE          Sampling probability rho (default: 1.0)
+      -u,--sub-sample          Perform sub-sampling; see below.
+      -s,--summary-statistics  Only output number of children for each branch
+      -S,--seed [INT]          Seed for random number generator; list of 32 bit
+                               integers with up to 256 elements (default: random)
+      -h,--help                Show this help text
+    
+    Height of Trees: if no tree height is given, the heights will be randomly drawn from the expected distribution given the number of leaves, the birth and the death rate.
+    Summary statistics only: only print (NumberOfExtantChildren BranchLength) pairs for each branch of each tree. The trees are separated by a newline character.
+    Sub-sampling: simulate one big tree with n'=round(n/rho), n'>=n, leaves, and randomly sample sub-trees with n leaves. Hence, with rho=1.0, the same tree is reported over and over again.
+    Gernhard, T. (2008). The conditioned reconstructed process. Journal of Theoretical Biology, 253(4), 769–778. http://doi.org/10.1016/j.jtbi.2008.04.005
+    
+    ELynx
+    -----
+    A Haskell library and tool set for computational biology. The goal of ELynx is
+    reproducible research. Evolutionary sequences and phylogenetic trees can be
+    read, viewed, modified and simulated. The command line with all arguments is
+    logged consistently, and automatically. Data integrity is verified using SHA256
+    sums so that validation of past analyses is possible without the need to
+    recompute the result.
+    
+    slynx     Analyze, modify, and simulate evolutionary sequences.
+    tlynx     Analyze, modify, and simulate phylogenetic trees.
+    elynx     Validate and redo past analyses.
+    
+    Get help for sub commands:
+      slynx examine --help
+
+
+# ELynx
+
+Validate and (optionally) redo past ELynx analyses.
+
+    elynx --help
+
+    ELynx Suite version 0.2.1.
+    Developed by Dominik Schrempf.
+    Compiled on April 27, 2020, at 06:31 am, UTC.
+    
+    Usage: elynx COMMAND
+      Validate and redo past ELynx analyses
+    
+    Available options:
+      -h,--help                Show this help text
+      -V,--version             Show version
+    
+    Available commands:
+      validate                 Validate an ELynx analysis
+      redo                     Redo an ELynx analysis
+    
+    
+    ELynx
+    -----
+    A Haskell library and tool set for computational biology. The goal of ELynx is
+    reproducible research. Evolutionary sequences and phylogenetic trees can be
+    read, viewed, modified and simulated. The command line with all arguments is
+    logged consistently, and automatically. Data integrity is verified using SHA256
+    sums so that validation of past analyses is possible without the need to
+    recompute the result.
+    
+    slynx     Analyze, modify, and simulate evolutionary sequences.
+    tlynx     Analyze, modify, and simulate phylogenetic trees.
+    elynx     Validate and redo past analyses.
+    
+    Get help for sub commands:
+      slynx examine --help
+
+
+# Library documentation
+
+Documentation of the libraries can be found on [Hackage](https://hackage.haskell.org/):
+
+-   [elynx-markov](https://hackage.haskell.org/package/elynx-markov)
+-   [elynx-seq](https://hackage.haskell.org/package/elynx-seq)
+-   [elynx-tools](https://hackage.haskell.org/package/elynx-tools)
+-   [elynx-tree](https://hackage.haskell.org/package/elynx-tree)
+
+Documentation of the executables is also available:
+
+-   [elynx](https://hackage.haskell.org/package/elynx)
+-   [slynx](https://hackage.haskell.org/package/slynx)
+-   [tlynx](https://hackage.haskell.org/package/tlynx)
+
diff --git a/elynx-markov.cabal b/elynx-markov.cabal
new file mode 100644
--- /dev/null
+++ b/elynx-markov.cabal
@@ -0,0 +1,92 @@
+cabal-version: 1.12
+name: elynx-markov
+version: 0.2.1
+license: GPL-3
+license-file: LICENSE
+copyright: Dominik Schrempf (2020)
+maintainer: dominik.schrempf@gmail.com
+author: Dominik Schrempf
+homepage: https://github.com/dschrempf/elynx#readme
+bug-reports: https://github.com/dschrempf/elynx/issues
+synopsis: Simulate molecular sequences along trees
+description:
+    Examine, modify, and simulate molecular sequences in a reproducible way. Please see the README on GitHub at <https://github.com/dschrempf/elynx>.
+category: Bioinformatics
+build-type: Simple
+extra-source-files:
+    README.md
+    ChangeLog.md
+
+source-repository head
+    type: git
+    location: https://github.com/dschrempf/elynx
+
+library
+    exposed-modules:
+        ELynx.Data.MarkovProcess.AminoAcid
+        ELynx.Data.MarkovProcess.CXXModels
+        ELynx.Data.MarkovProcess.CXXModelsData
+        ELynx.Data.MarkovProcess.GammaRateHeterogeneity
+        ELynx.Data.MarkovProcess.MixtureModel
+        ELynx.Data.MarkovProcess.Nucleotide
+        ELynx.Data.MarkovProcess.PhyloModel
+        ELynx.Data.MarkovProcess.RateMatrix
+        ELynx.Data.MarkovProcess.SubstitutionModel
+        ELynx.Import.MarkovProcess.EDMModelPhylobayes
+        ELynx.Import.MarkovProcess.SiteprofilesPhylobayes
+        ELynx.Simulate.MarkovProcess
+        ELynx.Simulate.MarkovProcessAlongTree
+    hs-source-dirs: src
+    other-modules:
+        Paths_elynx_markov
+    default-language: Haskell2010
+    ghc-options: -Wall -fllvm
+    build-depends:
+        base >=4.13.0.0 && <4.14,
+        bytestring >=0.10.10.0 && <0.11,
+        containers >=0.6.2.1 && <0.7,
+        elynx-seq >=0.2.1 && <0.3,
+        elynx-tools >=0.2.1 && <0.3,
+        elynx-tree >=0.2.1 && <0.3,
+        hmatrix >=0.20.0.0 && <0.21,
+        integration >=0.2.1 && <0.3,
+        math-functions >=0.3.3.0 && <0.4,
+        megaparsec >=8.0.0 && <8.1,
+        mwc-random >=0.14.0.0 && <0.15,
+        parallel >=3.2.2.0 && <3.3,
+        primitive >=0.7.0.1 && <0.8,
+        statistics >=0.15.2.0 && <0.16,
+        vector >=0.12.1.2 && <0.13
+
+test-suite markov-test
+    type: exitcode-stdio-1.0
+    main-is: Spec.hs
+    hs-source-dirs: test
+    other-modules:
+        ELynx.Data.MarkovProcess.AminoAcidSpec
+        ELynx.Data.MarkovProcess.NucleotideSpec
+        ELynx.Data.MarkovProcess.RateMatrixSpec
+        ELynx.Import.MarkovProcess.EDMModelPhylobayesSpec
+        ELynx.Import.MarkovProcess.SiteprofilesPhylobayesSpec
+        ELynx.Simulate.MarkovProcessAlongTreeSpec
+        Paths_elynx_markov
+    default-language: Haskell2010
+    ghc-options: -Wall -fllvm -threaded -rtsopts -with-rtsopts=-N
+    build-depends:
+        base >=4.13.0.0 && <4.14,
+        bytestring >=0.10.10.0 && <0.11,
+        containers >=0.6.2.1 && <0.7,
+        elynx-markov -any,
+        elynx-tools >=0.2.1 && <0.3,
+        elynx-tree >=0.2.1 && <0.3,
+        hmatrix >=0.20.0.0 && <0.21,
+        hspec >=2.7.1 && <2.8,
+        hspec-megaparsec >=2.1.0 && <2.2,
+        integration >=0.2.1 && <0.3,
+        math-functions >=0.3.3.0 && <0.4,
+        megaparsec >=8.0.0 && <8.1,
+        mwc-random >=0.14.0.0 && <0.15,
+        parallel >=3.2.2.0 && <3.3,
+        primitive >=0.7.0.1 && <0.8,
+        statistics >=0.15.2.0 && <0.16,
+        vector >=0.12.1.2 && <0.13
diff --git a/src/ELynx/Data/MarkovProcess/AminoAcid.hs b/src/ELynx/Data/MarkovProcess/AminoAcid.hs
new file mode 100644
--- /dev/null
+++ b/src/ELynx/Data/MarkovProcess/AminoAcid.hs
@@ -0,0 +1,620 @@
+{- |
+Module      :  ELynx.Data.MarkovProcess.AminoAcid
+Description :  Amino acid rate matrices such as LG
+Copyright   :  (c) Dominik Schrempf 2020
+License     :  GPL-3.0-or-later
+
+Maintainer  :  dominik.schrempf@gmail.com
+Stability   :  unstable
+Portability :  portable
+
+Creation date: Tue Jan 29 09:29:19 2019.
+
+The order of amino acids is alphabetic.
+
+-}
+
+module ELynx.Data.MarkovProcess.AminoAcid
+  ( lg
+  , lgCustom
+  , wag
+  , wagCustom
+  , poisson
+  , poissonCustom
+  , gtr20
+  )
+where
+
+import           Data.List                      ( elemIndex )
+import           Data.Maybe                     ( fromMaybe )
+import           Data.Word                      ( Word8 )
+import           Numeric.LinearAlgebra
+
+import           ELynx.Data.Alphabet.Alphabet
+
+import           ELynx.Tools
+
+import           ELynx.Data.MarkovProcess.RateMatrix
+import           ELynx.Data.MarkovProcess.SubstitutionModel
+
+n :: Int
+n = 20
+
+-- Some matrices have to be converted from PAML order to alphabetical order. See
+-- 'pamlToAlphaVec' and 'pamlToAlphaMat'.
+
+-- Amno acids in alphabetical order.
+aaAlphaOrder :: [Word8]
+aaAlphaOrder = map
+  c2w
+  [ 'A'
+  , 'C'
+  , 'D'
+  , 'E'
+  , 'F'
+  , 'G'
+  , 'H'
+  , 'I'
+  , 'K'
+  , 'L'
+  , 'M'
+  , 'N'
+  , 'P'
+  , 'Q'
+  , 'R'
+  , 'S'
+  , 'T'
+  , 'V'
+  , 'W'
+  , 'Y'
+  ]
+
+-- Amino acids in PAML oder.
+aaPamlOrder :: [Word8]
+aaPamlOrder = map
+  c2w
+  [ 'A'
+  , 'R'
+  , 'N'
+  , 'D'
+  , 'C'
+  , 'Q'
+  , 'E'
+  , 'G'
+  , 'H'
+  , 'I'
+  , 'L'
+  , 'K'
+  , 'M'
+  , 'F'
+  , 'P'
+  , 'S'
+  , 'T'
+  , 'W'
+  , 'Y'
+  , 'V'
+  ]
+
+-- -- This is a very slow implementation; since I only convert matrices once it
+-- -- should not be a problem. A map would be better if performance is an issue.
+-- pamlIndexToAlphaIndex :: Int -> Int
+-- pamlIndexToAlphaIndex i = fromMaybe
+--                           (error $ "Could not convert index " ++ show i ++ ".")
+--                           (elemIndex aa aaAlphaOrder)
+--   where aa = aaPamlOrder !! i
+
+-- This is a very slow implementation; since I only convert matrices once it
+-- should not be a problem. A map would be better if performance is an issue.
+alphaIndexToPamlIndex :: Int -> Int
+alphaIndexToPamlIndex i = fromMaybe
+  (error $ "Could not convert index " ++ show i ++ ".")
+  (elemIndex aa aaPamlOrder)
+  where aa = aaAlphaOrder !! i
+
+-- Convert an amino acid vector in PAML order to a vector in alphabetical order.
+pamlToAlphaVec :: Vector R -> Vector R
+pamlToAlphaVec v = build n (\i -> v ! alphaIndexToPamlIndex (round i))
+
+
+-- Convert an amino acid matrix in PAML order to a matrix in alphabetical order.
+pamlToAlphaMat :: Matrix R -> Matrix R
+pamlToAlphaMat m = build
+  (n, n)
+  (\i j -> m ! alphaIndexToPamlIndex (round i) ! alphaIndexToPamlIndex (round j)
+  )
+
+-- Lower triangular matrix of LG exchangeabilities in PAML order and in form of
+-- a list.
+lgExchRawPaml :: [Double]
+lgExchRawPaml =
+  [ 0.425093
+  , 0.276818
+  , 0.751878
+  , 0.395144
+  , 0.123954
+  , 5.076149
+  , 2.489084
+  , 0.534551
+  , 0.528768
+  , 0.062556
+  , 0.969894
+  , 2.807908
+  , 1.695752
+  , 0.523386
+  , 0.084808
+  , 1.038545
+  , 0.363970
+  , 0.541712
+  , 5.243870
+  , 0.003499
+  , 4.128591
+  , 2.066040
+  , 0.390192
+  , 1.437645
+  , 0.844926
+  , 0.569265
+  , 0.267959
+  , 0.348847
+  , 0.358858
+  , 2.426601
+  , 4.509238
+  , 0.927114
+  , 0.640543
+  , 4.813505
+  , 0.423881
+  , 0.311484
+  , 0.149830
+  , 0.126991
+  , 0.191503
+  , 0.010690
+  , 0.320627
+  , 0.072854
+  , 0.044265
+  , 0.008705
+  , 0.108882
+  , 0.395337
+  , 0.301848
+  , 0.068427
+  , 0.015076
+  , 0.594007
+  , 0.582457
+  , 0.069673
+  , 0.044261
+  , 0.366317
+  , 4.145067
+  , 0.536518
+  , 6.326067
+  , 2.145078
+  , 0.282959
+  , 0.013266
+  , 3.234294
+  , 1.807177
+  , 0.296636
+  , 0.697264
+  , 0.159069
+  , 0.137500
+  , 1.124035
+  , 0.484133
+  , 0.371004
+  , 0.025548
+  , 0.893680
+  , 1.672569
+  , 0.173735
+  , 0.139538
+  , 0.442472
+  , 4.273607
+  , 6.312358
+  , 0.656604
+  , 0.253701
+  , 0.052722
+  , 0.089525
+  , 0.017416
+  , 1.105251
+  , 0.035855
+  , 0.018811
+  , 0.089586
+  , 0.682139
+  , 1.112727
+  , 2.592692
+  , 0.023918
+  , 1.798853
+  , 1.177651
+  , 0.332533
+  , 0.161787
+  , 0.394456
+  , 0.075382
+  , 0.624294
+  , 0.419409
+  , 0.196961
+  , 0.508851
+  , 0.078281
+  , 0.249060
+  , 0.390322
+  , 0.099849
+  , 0.094464
+  , 4.727182
+  , 0.858151
+  , 4.008358
+  , 1.240275
+  , 2.784478
+  , 1.223828
+  , 0.611973
+  , 1.739990
+  , 0.990012
+  , 0.064105
+  , 0.182287
+  , 0.748683
+  , 0.346960
+  , 0.361819
+  , 1.338132
+  , 2.139501
+  , 0.578987
+  , 2.000679
+  , 0.425860
+  , 1.143480
+  , 1.080136
+  , 0.604545
+  , 0.129836
+  , 0.584262
+  , 1.033739
+  , 0.302936
+  , 1.136863
+  , 2.020366
+  , 0.165001
+  , 0.571468
+  , 6.472279
+  , 0.180717
+  , 0.593607
+  , 0.045376
+  , 0.029890
+  , 0.670128
+  , 0.236199
+  , 0.077852
+  , 0.268491
+  , 0.597054
+  , 0.111660
+  , 0.619632
+  , 0.049906
+  , 0.696175
+  , 2.457121
+  , 0.095131
+  , 0.248862
+  , 0.140825
+  , 0.218959
+  , 0.314440
+  , 0.612025
+  , 0.135107
+  , 1.165532
+  , 0.257336
+  , 0.120037
+  , 0.054679
+  , 5.306834
+  , 0.232523
+  , 0.299648
+  , 0.131932
+  , 0.481306
+  , 7.803902
+  , 0.089613
+  , 0.400547
+  , 0.245841
+  , 3.151815
+  , 2.547870
+  , 0.170887
+  , 0.083688
+  , 0.037967
+  , 1.959291
+  , 0.210332
+  , 0.245034
+  , 0.076701
+  , 0.119013
+  , 10.649107
+  , 1.702745
+  , 0.185202
+  , 1.898718
+  , 0.654683
+  , 0.296501
+  , 0.098369
+  , 2.188158
+  , 0.189510
+  , 0.249313
+  ]
+
+
+-- Exchangeabilities of LG model in alphabetical order.
+lgExch :: ExchangeabilityMatrix
+lgExch = pamlToAlphaMat $ exchFromListLower n lgExchRawPaml
+
+-- Stationary distribution in PAML order.
+lgStatDistPaml :: StationaryDistribution
+lgStatDistPaml = normalizeSumVec 1.0 $ fromList
+  [ 0.079066
+  , 0.055941
+  , 0.041977
+  , 0.053052
+  , 0.012937
+  , 0.040767
+  , 0.071586
+  , 0.057337
+  , 0.022355
+  , 0.062157
+  , 0.099081
+  , 0.064600
+  , 0.022951
+  , 0.042302
+  , 0.044040
+  , 0.061197
+  , 0.053287
+  , 0.012066
+  , 0.034155
+  , 0.069147
+  ]
+
+-- Stationary distribution of LG model in alphabetical order.
+lgStatDist :: StationaryDistribution
+lgStatDist = pamlToAlphaVec lgStatDistPaml
+
+-- | LG substitution model.
+lg :: SubstitutionModel
+lg = substitutionModel Protein "LG" [] lgStatDist lgExch
+
+-- | LG substitution model with maybe a name and a custom stationary distribution.
+lgCustom :: Maybe String -> StationaryDistribution -> SubstitutionModel
+lgCustom mnm d = substitutionModel Protein nm [] d lgExch
+  where nm = fromMaybe "LG-Custom" mnm
+
+-- WAG exchangeability list in PAML order.
+wagExchRawPaml :: [Double]
+wagExchRawPaml =
+  [ 55.15710
+  , 50.98480
+  , 63.53460
+  , 73.89980
+  , 14.73040
+  , 542.94200
+  , 102.70400
+  , 52.81910
+  , 26.52560
+  , 3.02949
+  , 90.85980
+  , 303.55000
+  , 154.36400
+  , 61.67830
+  , 9.88179
+  , 158.28500
+  , 43.91570
+  , 94.71980
+  , 617.41600
+  , 2.13520
+  , 546.94700
+  , 141.67200
+  , 58.46650
+  , 112.55600
+  , 86.55840
+  , 30.66740
+  , 33.00520
+  , 56.77170
+  , 31.69540
+  , 213.71500
+  , 395.62900
+  , 93.06760
+  , 24.89720
+  , 429.41100
+  , 57.00250
+  , 24.94100
+  , 19.33350
+  , 18.69790
+  , 55.42360
+  , 3.94370
+  , 17.01350
+  , 11.39170
+  , 12.73950
+  , 3.04501
+  , 13.81900
+  , 39.79150
+  , 49.76710
+  , 13.15280
+  , 8.48047
+  , 38.42870
+  , 86.94890
+  , 15.42630
+  , 6.13037
+  , 49.94620
+  , 317.09700
+  , 90.62650
+  , 535.14200
+  , 301.20100
+  , 47.98550
+  , 7.40339
+  , 389.49000
+  , 258.44300
+  , 37.35580
+  , 89.04320
+  , 32.38320
+  , 25.75550
+  , 89.34960
+  , 68.31620
+  , 19.82210
+  , 10.37540
+  , 39.04820
+  , 154.52600
+  , 31.51240
+  , 17.41000
+  , 40.41410
+  , 425.74600
+  , 485.40200
+  , 93.42760
+  , 21.04940
+  , 10.27110
+  , 9.61621
+  , 4.67304
+  , 39.80200
+  , 9.99208
+  , 8.11339
+  , 4.99310
+  , 67.93710
+  , 105.94700
+  , 211.51700
+  , 8.88360
+  , 119.06300
+  , 143.85500
+  , 67.94890
+  , 19.50810
+  , 42.39840
+  , 10.94040
+  , 93.33720
+  , 68.23550
+  , 24.35700
+  , 69.61980
+  , 9.99288
+  , 41.58440
+  , 55.68960
+  , 17.13290
+  , 16.14440
+  , 337.07900
+  , 122.41900
+  , 397.42300
+  , 107.17600
+  , 140.76600
+  , 102.88700
+  , 70.49390
+  , 134.18200
+  , 74.01690
+  , 31.94400
+  , 34.47390
+  , 96.71300
+  , 49.39050
+  , 54.59310
+  , 161.32800
+  , 212.11100
+  , 55.44130
+  , 203.00600
+  , 37.48660
+  , 51.29840
+  , 85.79280
+  , 82.27650
+  , 22.58330
+  , 47.33070
+  , 145.81600
+  , 32.66220
+  , 138.69800
+  , 151.61200
+  , 17.19030
+  , 79.53840
+  , 437.80200
+  , 11.31330
+  , 116.39200
+  , 7.19167
+  , 12.97670
+  , 71.70700
+  , 21.57370
+  , 15.65570
+  , 33.69830
+  , 26.25690
+  , 21.24830
+  , 66.53090
+  , 13.75050
+  , 51.57060
+  , 152.96400
+  , 13.94050
+  , 52.37420
+  , 11.08640
+  , 24.07350
+  , 38.15330
+  , 108.60000
+  , 32.57110
+  , 54.38330
+  , 22.77100
+  , 19.63030
+  , 10.36040
+  , 387.34400
+  , 42.01700
+  , 39.86180
+  , 13.32640
+  , 42.84370
+  , 645.42800
+  , 21.60460
+  , 78.69930
+  , 29.11480
+  , 248.53900
+  , 200.60100
+  , 25.18490
+  , 19.62460
+  , 15.23350
+  , 100.21400
+  , 30.12810
+  , 58.87310
+  , 18.72470
+  , 11.83580
+  , 782.13000
+  , 180.03400
+  , 30.54340
+  , 205.84500
+  , 64.98920
+  , 31.48870
+  , 23.27390
+  , 138.82300
+  , 36.53690
+  , 31.47300
+  ]
+
+-- WAG exchangeability matrix n alphabetical order.
+wagExch :: ExchangeabilityMatrix
+wagExch = pamlToAlphaMat $ exchFromListLower n wagExchRawPaml
+
+-- WAG stationary distribution in PAML order.
+wagStatDistPaml :: StationaryDistribution
+wagStatDistPaml = normalizeSumVec 1.0 $ fromList
+  [ 0.0866279
+  , 0.043972
+  , 0.0390894
+  , 0.0570451
+  , 0.0193078
+  , 0.0367281
+  , 0.0580589
+  , 0.0832518
+  , 0.0244313
+  , 0.048466
+  , 0.086209
+  , 0.0620286
+  , 0.0195027
+  , 0.0384319
+  , 0.0457631
+  , 0.0695179
+  , 0.0610127
+  , 0.0143859
+  , 0.0352742
+  , 0.0708957
+  ]
+
+-- WAG stationary distribution in alphabetical order.
+wagStatDist :: StationaryDistribution
+wagStatDist = pamlToAlphaVec wagStatDistPaml
+
+-- | LG substitution model.
+wag :: SubstitutionModel
+wag = substitutionModel Protein "WAG" [] wagStatDist wagExch
+
+-- | LG substitution model with maybe a name and a custom stationary distribution.
+wagCustom :: Maybe String -> StationaryDistribution -> SubstitutionModel
+wagCustom mnm d = substitutionModel Protein nm [] d wagExch
+  where nm = fromMaybe "WAG-Custom" mnm
+
+uniformExch :: ExchangeabilityMatrix
+uniformExch = matrixSetDiagToZero $ matrix n $ replicate (n * n) 1.0
+
+poissonExch :: ExchangeabilityMatrix
+poissonExch = uniformExch
+
+-- | Poisson substitution model.
+poisson :: SubstitutionModel
+poisson = substitutionModel Protein "Poisson" [] (uniformVec n) poissonExch
+
+-- | Poisson substitution model with maybe a name and a custom stationary distribution.
+poissonCustom :: Maybe String -> StationaryDistribution -> SubstitutionModel
+poissonCustom mnm d = substitutionModel Protein nm [] d poissonExch
+  where nm = fromMaybe "Poisson-Custom" mnm
+
+-- | General time reversible (GTR) substitution model for amino acids.
+gtr20 :: [Double] -> StationaryDistribution -> SubstitutionModel
+gtr20 es d = substitutionModel Protein "GTR" es d e
+  where e = exchFromListUpper n es
diff --git a/src/ELynx/Data/MarkovProcess/CXXModels.hs b/src/ELynx/Data/MarkovProcess/CXXModels.hs
new file mode 100644
--- /dev/null
+++ b/src/ELynx/Data/MarkovProcess/CXXModels.hs
@@ -0,0 +1,146 @@
+{- |
+Module      :  ELynx.Data.MarkovProcess.CXXModels
+Description :  C10 to C60 models
+Copyright   :  (c) Dominik Schrempf 2020
+License     :  GPL-3.0-or-later
+
+Maintainer  :  dominik.schrempf@gmail.com
+Stability   :  unstable
+Portability :  portable
+
+Creation date: Tue Feb 26 16:44:33 2019.
+
+Quang, L. S., Gascuel, O. & Lartillot, N. Empirical profile mixture models for
+phylogenetic reconstruction. Bioinformatics 24, 2317–2323 (2008).
+
+XXX: For now, I only provide Poisson exchangeabilities.
+
+-}
+
+module ELynx.Data.MarkovProcess.CXXModels
+  ( cxx
+  )
+where
+
+import           Data.List.NonEmpty             ( fromList )
+
+import           ELynx.Data.MarkovProcess.AminoAcid
+import           ELynx.Data.MarkovProcess.CXXModelsData
+import qualified ELynx.Data.MarkovProcess.MixtureModel
+                                               as M
+import           ELynx.Data.MarkovProcess.RateMatrix
+import qualified ELynx.Data.MarkovProcess.SubstitutionModel
+                                               as S
+
+-- | Create CXX model with given number of components and probably with custom
+-- weights.
+cxx :: Int -> Maybe [M.Weight] -> M.MixtureModel
+cxx 10 (Just ws) = c10CustomWeights ws
+cxx 20 (Just ws) = c20CustomWeights ws
+cxx 30 (Just ws) = c30CustomWeights ws
+cxx 40 (Just ws) = c40CustomWeights ws
+cxx 50 (Just ws) = c50CustomWeights ws
+cxx 60 (Just ws) = c60CustomWeights ws
+cxx 10 Nothing   = c10
+cxx 20 Nothing   = c20
+cxx 30 Nothing   = c30
+cxx 40 Nothing   = c40
+cxx 50 Nothing   = c50
+cxx 60 Nothing   = c60
+cxx n _ =
+  error $ "cxx: cannot create CXX model with " ++ show n ++ " components."
+
+-- | C10 model.
+c10 :: M.MixtureModel
+c10 = cxxFromStatDistsAndWeights c10Weights c10StatDists
+
+-- | C20 model.
+c20 :: M.MixtureModel
+c20 = cxxFromStatDistsAndWeights c20Weights c20StatDists
+
+-- | C30 model.
+c30 :: M.MixtureModel
+c30 = cxxFromStatDistsAndWeights c30Weights c30StatDists
+
+-- | C40 model.
+c40 :: M.MixtureModel
+c40 = cxxFromStatDistsAndWeights c40Weights c40StatDists
+
+-- | C50 model.
+c50 :: M.MixtureModel
+c50 = cxxFromStatDistsAndWeights c50Weights c50StatDists
+
+-- | C60 model.
+c60 :: M.MixtureModel
+c60 = cxxFromStatDistsAndWeights c60Weights c60StatDists
+
+-- | C10 model with custom weights.
+c10CustomWeights :: [M.Weight] -> M.MixtureModel
+c10CustomWeights ws
+  | length ws == 10 = cxxFromStatDistsAndWeights ws c10StatDists
+  | otherwise       = error "Number of weights does not match C10 model."
+
+-- | C20 model with custom weights.
+c20CustomWeights :: [M.Weight] -> M.MixtureModel
+c20CustomWeights ws
+  | length ws == 20 = cxxFromStatDistsAndWeights ws c20StatDists
+  | otherwise       = error "Number of weights does not match C20 model."
+
+-- | C30 model with custom weights.
+c30CustomWeights :: [M.Weight] -> M.MixtureModel
+c30CustomWeights ws
+  | length ws == 30 = cxxFromStatDistsAndWeights ws c30StatDists
+  | otherwise       = error "Number of weights does not match C30 model."
+
+-- | C40 model with custom weights.
+c40CustomWeights :: [M.Weight] -> M.MixtureModel
+c40CustomWeights ws
+  | length ws == 40 = cxxFromStatDistsAndWeights ws c40StatDists
+  | otherwise       = error "Number of weights does not match C40 model."
+
+-- | C50 model with custom weights.
+c50CustomWeights :: [M.Weight] -> M.MixtureModel
+c50CustomWeights ws
+  | length ws == 50 = cxxFromStatDistsAndWeights ws c50StatDists
+  | otherwise       = error "Number of weights does not match C50 model."
+
+-- | C60 model with custom weights.
+c60CustomWeights :: [M.Weight] -> M.MixtureModel
+c60CustomWeights ws
+  | length ws == 60 = cxxFromStatDistsAndWeights ws c60StatDists
+  | otherwise       = error "Number of weights does not match C60 model."
+
+cxxName :: Int -> String
+cxxName nComps = 'C' : show nComps
+
+componentName :: Int -> Int -> String
+componentName nComps comp = cxxName nComps ++ "; component " ++ show comp
+
+-- Keep in mind, that when using different exchangeabilities, I have to decide
+-- about global or local normalization.
+cxxSubstitutionModelFromStatDist
+  :: Int -> Int -> StationaryDistribution -> S.SubstitutionModel
+cxxSubstitutionModelFromStatDist nComps comp d = poissonCustom
+  (Just name)
+  (normalizeSD d)
+  where name = componentName nComps comp
+
+cxxSubstitutionModelsFromStatDists
+  :: [StationaryDistribution] -> [S.SubstitutionModel]
+cxxSubstitutionModelsFromStatDists ds = zipWith
+  (cxxSubstitutionModelFromStatDist nComp)
+  [1 ..]
+  ds
+  where nComp = length ds
+
+-- XXX: The use of `Data.List.NonEmpty.fromList` is daring, but since this
+-- function is not exported and only applied to predefined non-empty lists, it
+-- should be OK.
+cxxFromStatDistsAndWeights
+  :: [M.Weight] -> [StationaryDistribution] -> M.MixtureModel
+cxxFromStatDistsAndWeights ws ds = M.fromSubstitutionModels (cxxName n)
+                                                            (fromList ws)
+                                                            sms
+ where
+  n   = length ds
+  sms = fromList $ cxxSubstitutionModelsFromStatDists ds
diff --git a/src/ELynx/Data/MarkovProcess/CXXModelsData.hs b/src/ELynx/Data/MarkovProcess/CXXModelsData.hs
new file mode 100644
--- /dev/null
+++ b/src/ELynx/Data/MarkovProcess/CXXModelsData.hs
@@ -0,0 +1,4722 @@
+{- |
+Module      :  ELynx.Data.MarkovProcess.CXXModelsData
+Description :  Stationary distributions and weights
+Copyright   :  (c) Dominik Schrempf 2020
+License     :  GPL-3.0-or-later
+
+Maintainer  :  dominik.schrempf@gmail.com
+Stability   :  unstable
+Portability :  portable
+
+Creation date: Tue Feb 26 17:17:35 2019.
+
+Quang, L. S., Gascuel, O. & Lartillot, N. Empirical profile mixture models for
+phylogenetic reconstruction. Bioinformatics 24, 2317–2323 (2008).
+
+-}
+
+module ELynx.Data.MarkovProcess.CXXModelsData
+  ( c10StatDists
+  , c10Weights
+  , c20StatDists
+  , c20Weights
+  , c30StatDists
+  , c30Weights
+  , c40StatDists
+  , c40Weights
+  , c50StatDists
+  , c50Weights
+  , c60StatDists
+  , c60Weights
+  )
+where
+
+import qualified Data.Vector.Storable          as V
+
+import           ELynx.Data.MarkovProcess.RateMatrix
+
+-- | Stationary distribution of C10 model.
+c10StatDists :: [StationaryDistribution]
+c10StatDists = map
+  V.fromList
+  [ [ 0.408257
+    , 0.0349388
+    , 0.00698709
+    , 0.00978467
+    , 0.00616043
+    , 0.122161
+    , 0.00391518
+    , 0.0125784
+    , 0.00596702
+    , 0.0158339
+    , 0.00813132
+    , 0.00962854
+    , 0.0394156
+    , 0.00752797
+    , 0.0081783
+    , 0.168245
+    , 0.0658133
+    , 0.0604427
+    , 0.00187516
+    , 0.00415797
+    ]
+  , [ 0.102776
+    , 0.0149663
+    , 0.0155944
+    , 0.0419667
+    , 0.0180729
+    , 0.0138806
+    , 0.0158865
+    , 0.106608
+    , 0.0436344
+    , 0.113194
+    , 0.04378
+    , 0.0213272
+    , 0.0223251
+    , 0.0440685
+    , 0.0418664
+    , 0.0529608
+    , 0.108174
+    , 0.160665
+    , 0.00451472
+    , 0.0137374
+    ]
+  , [ 0.0351766
+    , 0.00787065
+    , 0.000676874
+    , 0.00196868
+    , 0.0126221
+    , 0.00224206
+    , 0.00128783
+    , 0.351582
+    , 0.00188565
+    , 0.127818
+    , 0.0242632
+    , 0.00165915
+    , 0.00297716
+    , 0.00165596
+    , 0.00196786
+    , 0.00499981
+    , 0.0255378
+    , 0.388864
+    , 0.00119078
+    , 0.00375393
+    ]
+  , [ 0.0408514
+    , 0.00376029
+    , 0.233381
+    , 0.0901239
+    , 0.00251082
+    , 0.115833
+    , 0.0373197
+    , 0.00255236
+    , 0.0485017
+    , 0.00521646
+    , 0.00225718
+    , 0.218565
+    , 0.0108334
+    , 0.0380451
+    , 0.0269887
+    , 0.0804527
+    , 0.030288
+    , 0.00444811
+    , 0.00108153
+    , 0.00698909
+    ]
+  , [ 0.0185493
+    , 0.00704165
+    , 0.000977506
+    , 0.00248916
+    , 0.073333
+    , 0.00289529
+    , 0.0040104
+    , 0.163242
+    , 0.00435709
+    , 0.444308
+    , 0.120282
+    , 0.00248957
+    , 0.00488276
+    , 0.00835394
+    , 0.00623624
+    , 0.00516424
+    , 0.0131807
+    , 0.0968581
+    , 0.00687598
+    , 0.0144734
+    ]
+  , [ 0.110675
+    , 0.00148349
+    , 0.163644
+    , 0.263846
+    , 0.00232568
+    , 0.0325228
+    , 0.0163804
+    , 0.00683349
+    , 0.0677158
+    , 0.014068
+    , 0.00489881
+    , 0.0405186
+    , 0.0298982
+    , 0.0877962
+    , 0.035219
+    , 0.0562888
+    , 0.0426922
+    , 0.0181079
+    , 0.0010339
+    , 0.00405223
+    ]
+  , [ 0.0522658
+    , 0.0143325
+    , 0.0297745
+    , 0.0388387
+    , 0.0624033
+    , 0.0228101
+    , 0.155164
+    , 0.0187406
+    , 0.0439469
+    , 0.065378
+    , 0.0207189
+    , 0.0714837
+    , 0.0145475
+    , 0.073654
+    , 0.0668295
+    , 0.0549018
+    , 0.037014
+    , 0.0267512
+    , 0.0193757
+    , 0.111069
+    ]
+  , [ 0.0116587
+    , 0.0105341
+    , 0.00217425
+    , 0.00242511
+    , 0.365099
+    , 0.00347091
+    , 0.0366787
+    , 0.0187185
+    , 0.00266947
+    , 0.067649
+    , 0.0143535
+    , 0.00640111
+    , 0.00311599
+    , 0.00402037
+    , 0.00509901
+    , 0.00948485
+    , 0.00737139
+    , 0.0206341
+    , 0.0509565
+    , 0.357486
+    ]
+  , [ 0.0627196
+    , 0.00526629
+    , 0.0236193
+    , 0.0686285
+    , 0.00391818
+    , 0.0256175
+    , 0.0332612
+    , 0.0128968
+    , 0.227084
+    , 0.0305628
+    , 0.0124037
+    , 0.0428629
+    , 0.0140441
+    , 0.109811
+    , 0.203878
+    , 0.0483152
+    , 0.0463378
+    , 0.0197063
+    , 0.00251435
+    , 0.00655211
+    ]
+  , [ 0.114552
+    , 0.00985495
+    , 0.0416192
+    , 0.0364908
+    , 0.0046606
+    , 0.0503818
+    , 0.0165233
+    , 0.00929495
+    , 0.0423027
+    , 0.0139154
+    , 0.00822408
+    , 0.0750615
+    , 0.0379222
+    , 0.0339625
+    , 0.0324009
+    , 0.261065
+    , 0.184583
+    , 0.0195769
+    , 0.0017549
+    , 0.00585383
+    ]
+  ]
+
+-- | Weights of C10 model.
+c10Weights :: [Double]
+c10Weights =
+  [ 0.119134
+  , 0.0874372
+  , 0.103711
+  , 0.0922585
+  , 0.107049
+  , 0.132995
+  , 0.0538028
+  , 0.0691986
+  , 0.131994
+  , 0.10242
+  ]
+
+-- | Stationary distribution of C20 model.
+c20StatDists :: [StationaryDistribution]
+c20StatDists = map
+  V.fromList
+  [ [ 0.0862413
+    , 0.0130505
+    , 0.0329909
+    , 0.0184527
+    , 0.00441553
+    , 0.0366905
+    , 0.0108013
+    , 0.00979071
+    , 0.0220195
+    , 0.0112826
+    , 0.00878215
+    , 0.0791293
+    , 0.0189273
+    , 0.0169047
+    , 0.0171944
+    , 0.317815
+    , 0.27117
+    , 0.0179753
+    , 0.00153173
+    , 0.00483429
+    ]
+  , [ 0.203558
+    , 0.0348667
+    , 0.00316561
+    , 0.00708594
+    , 0.0112429
+    , 0.0195236
+    , 0.0024392
+    , 0.115257
+    , 0.00423808
+    , 0.0789777
+    , 0.0309187
+    , 0.00770524
+    , 0.0164189
+    , 0.00640441
+    , 0.00509808
+    , 0.0496777
+    , 0.111895
+    , 0.284906
+    , 0.00177626
+    , 0.00484482
+    ]
+  , [ 0.0211547
+    , 0.00481886
+    , 0.000549287
+    , 0.00145396
+    , 0.0128252
+    , 0.00114309
+    , 0.00113464
+    , 0.392846
+    , 0.00135799
+    , 0.125064
+    , 0.0209789
+    , 0.0012755
+    , 0.00202472
+    , 0.00123288
+    , 0.00149462
+    , 0.00262407
+    , 0.0171914
+    , 0.386068
+    , 0.00115911
+    , 0.0036028
+    ]
+  , [ 0.0376904
+    , 0.00640738
+    , 0.0109469
+    , 0.0358365
+    , 0.00363498
+    , 0.0191107
+    , 0.0329514
+    , 0.0101712
+    , 0.289763
+    , 0.0237496
+    , 0.00965289
+    , 0.0365411
+    , 0.0105337
+    , 0.0893564
+    , 0.28852
+    , 0.0356314
+    , 0.0355927
+    , 0.0144622
+    , 0.00279252
+    , 0.00665572
+    ]
+  , [ 0.00845978
+    , 0.0084909
+    , 0.00244879
+    , 0.00250555
+    , 0.342046
+    , 0.00242771
+    , 0.0433214
+    , 0.0097713
+    , 0.0026741
+    , 0.0380507
+    , 0.00807248
+    , 0.00725259
+    , 0.00214187
+    , 0.00427815
+    , 0.00535899
+    , 0.00804189
+    , 0.00553221
+    , 0.012141
+    , 0.049484
+    , 0.4375
+    ]
+  , [ 0.17599
+    , 0.00175587
+    , 0.130126
+    , 0.218217
+    , 0.0025277
+    , 0.0409535
+    , 0.0130708
+    , 0.00856221
+    , 0.0542946
+    , 0.0159531
+    , 0.00540458
+    , 0.0332846
+    , 0.037102
+    , 0.0707184
+    , 0.0290429
+    , 0.0793481
+    , 0.0540083
+    , 0.0249553
+    , 0.00105921
+    , 0.00362591
+    ]
+  , [ 0.16344
+    , 0.00886599
+    , 0.0374273
+    , 0.0220612
+    , 0.00306413
+    , 0.529672
+    , 0.00900061
+    , 0.00175694
+    , 0.0167118
+    , 0.00611563
+    , 0.00293908
+    , 0.0438702
+    , 0.0126458
+    , 0.0137555
+    , 0.0195541
+    , 0.0829343
+    , 0.0142836
+    , 0.00579857
+    , 0.00286407
+    , 0.00323983
+    ]
+  , [ 0.0917469
+    , 0.0284015
+    , 0.0133819
+    , 0.0196876
+    , 0.0998479
+    , 0.0249899
+    , 0.0449766
+    , 0.0583556
+    , 0.0164916
+    , 0.115501
+    , 0.0395995
+    , 0.0290699
+    , 0.0209916
+    , 0.0255085
+    , 0.0265853
+    , 0.0736483
+    , 0.0661518
+    , 0.0831856
+    , 0.0246464
+    , 0.0972327
+    ]
+  , [ 0.0646701
+    , 0.00771176
+    , 0.0168734
+    , 0.0544978
+    , 0.0219148
+    , 0.0148894
+    , 0.0313852
+    , 0.0505983
+    , 0.0907931
+    , 0.184428
+    , 0.077484
+    , 0.0228907
+    , 0.0105004
+    , 0.0996415
+    , 0.0988016
+    , 0.0321196
+    , 0.0411766
+    , 0.0505824
+    , 0.0084303
+    , 0.0206106
+    ]
+  , [ 0.0135994
+    , 0.010009
+    , 0.00079517
+    , 0.00180118
+    , 0.264097
+    , 0.00267946
+    , 0.00724019
+    , 0.0814027
+    , 0.00251581
+    , 0.366142
+    , 0.0734965
+    , 0.00184694
+    , 0.00389941
+    , 0.00464208
+    , 0.00434084
+    , 0.00436688
+    , 0.00752485
+    , 0.0573473
+    , 0.0261565
+    , 0.0660971
+    ]
+  , [ 0.147804
+    , 0.00488258
+    , 0.0534743
+    , 0.0727246
+    , 0.00299039
+    , 0.0907726
+    , 0.0262289
+    , 0.00357811
+    , 0.105166
+    , 0.0126777
+    , 0.00596218
+    , 0.072663
+    , 0.0156558
+    , 0.0757166
+    , 0.0842845
+    , 0.14599
+    , 0.0634877
+    , 0.00927198
+    , 0.00159285
+    , 0.00507607
+    ]
+  , [ 0.0186377
+    , 0.00549689
+    , 0.00083297
+    , 0.00202485
+    , 0.0385383
+    , 0.00217135
+    , 0.0023666
+    , 0.202081
+    , 0.00291207
+    , 0.437038
+    , 0.124186
+    , 0.00198652
+    , 0.00406723
+    , 0.00658901
+    , 0.00420552
+    , 0.00461774
+    , 0.0149904
+    , 0.118938
+    , 0.00268717
+    , 0.00563241
+    ]
+  , [ 0.0477624
+    , 0.00757917
+    , 0.0141349
+    , 0.0462688
+    , 0.0130691
+    , 0.00523279
+    , 0.0165352
+    , 0.17415
+    , 0.0577575
+    , 0.112125
+    , 0.0330288
+    , 0.0209574
+    , 0.0124375
+    , 0.0429297
+    , 0.0505743
+    , 0.0264989
+    , 0.0951755
+    , 0.20937
+    , 0.00316605
+    , 0.0112466
+    ]
+  , [ 0.416419
+    , 0.0406938
+    , 0.00451317
+    , 0.00632298
+    , 0.00484384
+    , 0.0946185
+    , 0.00310574
+    , 0.00764432
+    , 0.00389418
+    , 0.00998854
+    , 0.00693232
+    , 0.00917014
+    , 0.0187841
+    , 0.00613205
+    , 0.00561008
+    , 0.236077
+    , 0.0746275
+    , 0.0459225
+    , 0.00121726
+    , 0.00348258
+    ]
+  , [ 0.0402296
+    , 0.0124783
+    , 0.0365524
+    , 0.0372197
+    , 0.0459095
+    , 0.0233618
+    , 0.210831
+    , 0.00934787
+    , 0.0482411
+    , 0.0360561
+    , 0.010029
+    , 0.103665
+    , 0.0098504
+    , 0.0826558
+    , 0.0735203
+    , 0.0533383
+    , 0.0310209
+    , 0.015248
+    , 0.0140077
+    , 0.106438
+    ]
+  , [ 0.0323453
+    , 0.00359763
+    , 0.24315
+    , 0.0710274
+    , 0.00244293
+    , 0.101607
+    , 0.0366225
+    , 0.00314108
+    , 0.0470129
+    , 0.00519805
+    , 0.00240287
+    , 0.252045
+    , 0.00948378
+    , 0.0330831
+    , 0.0236283
+    , 0.0848355
+    , 0.0359083
+    , 0.00487046
+    , 0.000873093
+    , 0.00672477
+    ]
+  , [ 0.147626
+    , 0.00323272
+    , 0.0403052
+    , 0.0576893
+    , 0.00471772
+    , 0.0330851
+    , 0.0146393
+    , 0.0108267
+    , 0.0451351
+    , 0.0256201
+    , 0.00586514
+    , 0.0211973
+    , 0.347371
+    , 0.0371554
+    , 0.0334507
+    , 0.0892065
+    , 0.0485899
+    , 0.0282336
+    , 0.00163587
+    , 0.00441772
+    ]
+  , [ 0.103145
+    , 0.00617625
+    , 0.0386402
+    , 0.0923369
+    , 0.00676664
+    , 0.0202338
+    , 0.0246762
+    , 0.0376904
+    , 0.0921699
+    , 0.0376284
+    , 0.0161883
+    , 0.0435172
+    , 0.0128302
+    , 0.0786603
+    , 0.0717748
+    , 0.095145
+    , 0.137857
+    , 0.0740454
+    , 0.00221447
+    , 0.00830416
+    ]
+  , [ 0.0837543
+    , 0.00207351
+    , 0.0804871
+    , 0.194776
+    , 0.00230634
+    , 0.022903
+    , 0.0268459
+    , 0.00740798
+    , 0.145929
+    , 0.019025
+    , 0.00673952
+    , 0.0518811
+    , 0.0085616
+    , 0.14565
+    , 0.0899383
+    , 0.045574
+    , 0.0451081
+    , 0.0150303
+    , 0.00107713
+    , 0.00493253
+    ]
+  , [ 0.0578736
+    , 0.00111308
+    , 0.294674
+    , 0.34021
+    , 0.00170349
+    , 0.0293911
+    , 0.0139817
+    , 0.00305257
+    , 0.0363365
+    , 0.00626119
+    , 0.0027296
+    , 0.0491422
+    , 0.0156106
+    , 0.059825
+    , 0.0138314
+    , 0.0358045
+    , 0.0249942
+    , 0.00876742
+    , 0.000866434
+    , 0.0038313
+    ]
+  ]
+
+-- | Weights of C20 model.
+c20Weights :: [Double]
+c20Weights =
+  [ 0.0559911
+  , 0.0514825
+  , 0.0812922
+  , 0.0721977
+  , 0.0556719
+  , 0.0331003
+  , 0.0589502
+  , 0.0263757
+  , 0.0307584
+  , 0.0376701
+  , 0.0303058
+  , 0.0808776
+  , 0.0263349
+  , 0.0579101
+  , 0.0371248
+  , 0.0586868
+  , 0.0561479
+  , 0.0349811
+  , 0.0544937
+  , 0.0596472
+  ]
+
+-- | Stationary distribution of C30 model.
+c30StatDists :: [StationaryDistribution]
+c30StatDists = map
+  V.fromList
+  [ [ 0.110045
+    , 0.00190472
+    , 0.159541
+    , 0.109896
+    , 0.00166295
+    , 0.0684302
+    , 0.0137951
+    , 0.00262831
+    , 0.0358554
+    , 0.00733965
+    , 0.00247064
+    , 0.0640338
+    , 0.166936
+    , 0.0310187
+    , 0.0171295
+    , 0.138179
+    , 0.0568343
+    , 0.00823656
+    , 0.000466112
+    , 0.00359702
+    ]
+  , [ 0.0874125
+    , 0.00498264
+    , 0.032612
+    , 0.0951701
+    , 0.00489966
+    , 0.0144043
+    , 0.0210627
+    , 0.0399884
+    , 0.11472
+    , 0.0301585
+    , 0.0126489
+    , 0.0382152
+    , 0.0137397
+    , 0.0798169
+    , 0.080632
+    , 0.087377
+    , 0.155862
+    , 0.0793881
+    , 0.00151228
+    , 0.00539745
+    ]
+  , [ 0.0225477
+    , 0.00500182
+    , 0.000595928
+    , 0.00150305
+    , 0.0089216
+    , 0.0011571
+    , 0.000937432
+    , 0.394469
+    , 0.00136009
+    , 0.0889573
+    , 0.0189103
+    , 0.00130346
+    , 0.0018312
+    , 0.00114366
+    , 0.00149005
+    , 0.00283364
+    , 0.0189813
+    , 0.425056
+    , 0.000669375
+    , 0.00233037
+    ]
+  , [ 0.0602158
+    , 0.000952546
+    , 0.290008
+    , 0.361087
+    , 0.00146256
+    , 0.0281926
+    , 0.0130501
+    , 0.00305162
+    , 0.0352705
+    , 0.00604019
+    , 0.00274606
+    , 0.0414988
+    , 0.0127175
+    , 0.0621611
+    , 0.0136833
+    , 0.0318109
+    , 0.022528
+    , 0.00932584
+    , 0.000794803
+    , 0.00340246
+    ]
+  , [ 0.0101224
+    , 0.00859894
+    , 0.000637919
+    , 0.00112496
+    , 0.278538
+    , 0.00240852
+    , 0.00477534
+    , 0.0701153
+    , 0.00167485
+    , 0.413591
+    , 0.0744863
+    , 0.00129289
+    , 0.00404666
+    , 0.00350286
+    , 0.00283449
+    , 0.00370872
+    , 0.00523793
+    , 0.040886
+    , 0.0200223
+    , 0.0523939
+    ]
+  , [ 0.133583
+    , 0.00105145
+    , 0.112578
+    , 0.209957
+    , 0.00167936
+    , 0.0207552
+    , 0.012133
+    , 0.00735265
+    , 0.0771772
+    , 0.0133278
+    , 0.00305717
+    , 0.0213892
+    , 0.18902
+    , 0.0565844
+    , 0.028479
+    , 0.0484054
+    , 0.0373318
+    , 0.0225174
+    , 0.000926699
+    , 0.00269464
+    ]
+  , [ 0.0408277
+    , 0.0153918
+    , 0.00306349
+    , 0.00660109
+    , 0.157505
+    , 0.00581131
+    , 0.0245212
+    , 0.148751
+    , 0.00759232
+    , 0.16378
+    , 0.0385527
+    , 0.00804649
+    , 0.00583522
+    , 0.0102922
+    , 0.0124492
+    , 0.0151579
+    , 0.033222
+    , 0.154771
+    , 0.0264937
+    , 0.121334
+    ]
+  , [ 0.246906
+    , 0.103941
+    , 0.00274183
+    , 0.00549448
+    , 0.0251776
+    , 0.0373263
+    , 0.00857523
+    , 0.0292404
+    , 0.00561231
+    , 0.0535091
+    , 0.0302246
+    , 0.016893
+    , 0.00780989
+    , 0.0103988
+    , 0.0106279
+    , 0.164235
+    , 0.123989
+    , 0.0955868
+    , 0.00531559
+    , 0.0163954
+    ]
+  , [ 0.0549429
+    , 0.0099281
+    , 0.00929153
+    , 0.0417085
+    , 0.024386
+    , 0.0105564
+    , 0.0363512
+    , 0.0569585
+    , 0.115252
+    , 0.168183
+    , 0.0592328
+    , 0.0202958
+    , 0.00830554
+    , 0.0906036
+    , 0.130543
+    , 0.0283779
+    , 0.0412594
+    , 0.0592101
+    , 0.00963554
+    , 0.024978
+    ]
+  , [ 0.0462773
+    , 0.0172727
+    , 0.0182504
+    , 0.0224266
+    , 0.133632
+    , 0.0160971
+    , 0.135785
+    , 0.0164967
+    , 0.0239396
+    , 0.0598936
+    , 0.0164507
+    , 0.0412365
+    , 0.0117413
+    , 0.0348991
+    , 0.0362984
+    , 0.0454156
+    , 0.0304388
+    , 0.0253979
+    , 0.0330338
+    , 0.235016
+    ]
+  , [ 0.047438
+    , 0.00823324
+    , 0.0112117
+    , 0.0388101
+    , 0.0116644
+    , 0.00559986
+    , 0.0149157
+    , 0.183217
+    , 0.0467851
+    , 0.110069
+    , 0.0356444
+    , 0.0222454
+    , 0.0100245
+    , 0.0374051
+    , 0.041018
+    , 0.0317171
+    , 0.111435
+    , 0.219931
+    , 0.00266856
+    , 0.00996601
+    ]
+  , [ 0.0213608
+    , 0.00610249
+    , 0.00129412
+    , 0.00362973
+    , 0.0371808
+    , 0.0030017
+    , 0.00384259
+    , 0.130947
+    , 0.00545678
+    , 0.456699
+    , 0.194784
+    , 0.0039879
+    , 0.00407473
+    , 0.0139566
+    , 0.00699762
+    , 0.00769915
+    , 0.0198019
+    , 0.0693208
+    , 0.00340864
+    , 0.00645457
+    ]
+  , [ 0.0919632
+    , 0.0117031
+    , 0.0306717
+    , 0.0171908
+    , 0.00415894
+    , 0.0370685
+    , 0.0100793
+    , 0.00931237
+    , 0.0205386
+    , 0.0097241
+    , 0.00757673
+    , 0.0764682
+    , 0.0179686
+    , 0.016006
+    , 0.0160005
+    , 0.325447
+    , 0.274438
+    , 0.0178218
+    , 0.00138874
+    , 0.00447397
+    ]
+  , [ 0.464925
+    , 0.0233329
+    , 0.00507317
+    , 0.00579942
+    , 0.00255882
+    , 0.149524
+    , 0.00232984
+    , 0.00433612
+    , 0.00285254
+    , 0.00559955
+    , 0.00393132
+    , 0.00753048
+    , 0.0186467
+    , 0.00435713
+    , 0.00430132
+    , 0.215019
+    , 0.047703
+    , 0.0292668
+    , 0.00090381
+    , 0.00200872
+    ]
+  , [ 0.205133
+    , 0.00209159
+    , 0.107098
+    , 0.198973
+    , 0.00182351
+    , 0.0487574
+    , 0.0127143
+    , 0.00581247
+    , 0.0667787
+    , 0.0133472
+    , 0.00437834
+    , 0.0339418
+    , 0.0110998
+    , 0.0822742
+    , 0.0439661
+    , 0.0873962
+    , 0.0519782
+    , 0.0193174
+    , 0.00073616
+    , 0.00238214
+    ]
+  , [ 0.026369
+    , 0.00394624
+    , 0.311772
+    , 0.0694354
+    , 0.00233519
+    , 0.0799842
+    , 0.0309615
+    , 0.00275212
+    , 0.0288631
+    , 0.00385797
+    , 0.00183637
+    , 0.272716
+    , 0.00624576
+    , 0.0218979
+    , 0.0133614
+    , 0.0798729
+    , 0.0324143
+    , 0.00427053
+    , 0.000722966
+    , 0.00638577
+    ]
+  , [ 0.15265
+    , 0.00402153
+    , 0.0237392
+    , 0.0377949
+    , 0.00585844
+    , 0.0306214
+    , 0.014193
+    , 0.0123318
+    , 0.0375543
+    , 0.0290062
+    , 0.00644732
+    , 0.016823
+    , 0.38645
+    , 0.0341734
+    , 0.0332784
+    , 0.0880336
+    , 0.0489543
+    , 0.0313553
+    , 0.00182526
+    , 0.00488778
+    ]
+  , [ 0.00802476
+    , 0.00234121
+    , 0.000338596
+    , 0.000781895
+    , 0.0311968
+    , 0.000540383
+    , 0.00100264
+    , 0.317706
+    , 0.00125983
+    , 0.373789
+    , 0.0488212
+    , 0.00063274
+    , 0.00206875
+    , 0.00155079
+    , 0.00174086
+    , 0.00120951
+    , 0.00656968
+    , 0.19446
+    , 0.00163092
+    , 0.00433436
+    ]
+  , [ 0.059995
+    , 0.0016885
+    , 0.0889731
+    , 0.0962701
+    , 0.00118007
+    , 0.0588796
+    , 0.0327277
+    , 0.00214673
+    , 0.182586
+    , 0.00708764
+    , 0.00339794
+    , 0.133492
+    , 0.0141408
+    , 0.0864856
+    , 0.100054
+    , 0.0779002
+    , 0.0448817
+    , 0.00422414
+    , 0.000624903
+    , 0.00326411
+    ]
+  , [ 0.0393521
+    , 0.00990719
+    , 0.0431198
+    , 0.039464
+    , 0.0188681
+    , 0.0282866
+    , 0.209572
+    , 0.00761014
+    , 0.0596434
+    , 0.025834
+    , 0.00845867
+    , 0.142548
+    , 0.00968405
+    , 0.101979
+    , 0.0838171
+    , 0.0624999
+    , 0.0347088
+    , 0.0127686
+    , 0.00546458
+    , 0.0564145
+    ]
+  , [ 0.00727155
+    , 0.00678525
+    , 0.00276038
+    , 0.00250694
+    , 0.127148
+    , 0.00808347
+    , 0.0113218
+    , 0.00566096
+    , 0.00177351
+    , 0.03942
+    , 0.00798661
+    , 0.00197568
+    , 0.00410981
+    , 0.00433393
+    , 0.0140999
+    , 0.00522444
+    , 0.00430223
+    , 0.00942264
+    , 0.627357
+    , 0.108456
+    ]
+  , [ 0.090707
+    , 0.00636999
+    , 0.0745873
+    , 0.0386802
+    , 0.00288592
+    , 0.475005
+    , 0.016809
+    , 0.00147211
+    , 0.0343856
+    , 0.00551498
+    , 0.00246921
+    , 0.0860678
+    , 0.0112151
+    , 0.0259377
+    , 0.0290062
+    , 0.073111
+    , 0.0153706
+    , 0.00392819
+    , 0.00229148
+    , 0.00418607
+    ]
+  , [ 0.00552919
+    , 0.00721059
+    , 0.00114134
+    , 0.000968304
+    , 0.374409
+    , 0.0016071
+    , 0.0325831
+    , 0.00829184
+    , 0.00138494
+    , 0.0353678
+    , 0.00744868
+    , 0.00460866
+    , 0.00133746
+    , 0.00226922
+    , 0.00246263
+    , 0.00574027
+    , 0.00372796
+    , 0.00988026
+    , 0.0330334
+    , 0.460998
+    ]
+  , [ 0.244326
+    , 0.027388
+    , 0.00315909
+    , 0.00767156
+    , 0.00606194
+    , 0.019609
+    , 0.00201894
+    , 0.101744
+    , 0.00454923
+    , 0.0468424
+    , 0.0201286
+    , 0.00624227
+    , 0.0185219
+    , 0.0053594
+    , 0.00453866
+    , 0.0497754
+    , 0.11708
+    , 0.310493
+    , 0.000957725
+    , 0.00353337
+    ]
+  , [ 0.0863111
+    , 0.00244198
+    , 0.0600903
+    , 0.20361
+    , 0.00293931
+    , 0.0175221
+    , 0.0245245
+    , 0.0105994
+    , 0.148579
+    , 0.027121
+    , 0.00958244
+    , 0.0313963
+    , 0.00682768
+    , 0.167235
+    , 0.0984812
+    , 0.03478
+    , 0.0408211
+    , 0.0202271
+    , 0.00140013
+    , 0.00551054
+    ]
+  , [ 0.0643926
+    , 0.00231659
+    , 0.162821
+    , 0.17627
+    , 0.00430667
+    , 0.0297139
+    , 0.0303504
+    , 0.0088163
+    , 0.072714
+    , 0.0148017
+    , 0.00567484
+    , 0.103121
+    , 0.00992703
+    , 0.0752535
+    , 0.0369049
+    , 0.0926434
+    , 0.083313
+    , 0.0161551
+    , 0.00112371
+    , 0.00938015
+    ]
+  , [ 0.173668
+    , 0.00835966
+    , 0.0285985
+    , 0.0483894
+    , 0.0058274
+    , 0.0781901
+    , 0.0266135
+    , 0.00686419
+    , 0.0964012
+    , 0.0219499
+    , 0.0112303
+    , 0.0520405
+    , 0.0169661
+    , 0.0722447
+    , 0.0943629
+    , 0.15478
+    , 0.0751702
+    , 0.0172524
+    , 0.00287745
+    , 0.00821304
+    ]
+  , [ 0.0347857
+    , 0.00627549
+    , 0.00923552
+    , 0.0323568
+    , 0.00343035
+    , 0.0170288
+    , 0.0306439
+    , 0.00919323
+    , 0.302085
+    , 0.0224429
+    , 0.00937208
+    , 0.0314157
+    , 0.0104447
+    , 0.0861073
+    , 0.307598
+    , 0.0326883
+    , 0.0328713
+    , 0.0130832
+    , 0.00252449
+    , 0.00641713
+    ]
+  , [ 0.108774
+    , 0.0247877
+    , 0.00158232
+    , 0.00417699
+    , 0.0316523
+    , 0.0134703
+    , 0.00247658
+    , 0.164346
+    , 0.00270004
+    , 0.233715
+    , 0.0539213
+    , 0.00326798
+    , 0.0154887
+    , 0.0057932
+    , 0.0051781
+    , 0.0188188
+    , 0.0474912
+    , 0.251283
+    , 0.00376565
+    , 0.00731064
+    ]
+  , [ 0.110101
+    , 0.00726998
+    , 0.0579269
+    , 0.0828181
+    , 0.0269154
+    , 0.0314463
+    , 0.0308557
+    , 0.0530866
+    , 0.029386
+    , 0.109679
+    , 0.0458729
+    , 0.0435099
+    , 0.0296431
+    , 0.0615197
+    , 0.0324325
+    , 0.0715888
+    , 0.0685882
+    , 0.0754042
+    , 0.00623241
+    , 0.0257238
+    ]
+  ]
+
+-- | Weights of C30 model.
+c30Weights :: [Double]
+c30Weights =
+  [ 0.00957833
+  , 0.0248476
+  , 0.0636309
+  , 0.0537939
+  , 0.0295886
+  , 0.0117588
+  , 0.0132013
+  , 0.0236869
+  , 0.0261688
+  , 0.0239822
+  , 0.0257101
+  , 0.0465072
+  , 0.0546795
+  , 0.0536085
+  , 0.0270623
+  , 0.0403914
+  , 0.0474213
+  , 0.0458816
+  , 0.0214037
+  , 0.0290386
+  , 0.0123392
+  , 0.056935
+  , 0.0419688
+  , 0.0339027
+  , 0.0388777
+  , 0.0196344
+  , 0.0233086
+  , 0.0622723
+  , 0.0184803
+  , 0.0203395
+  ]
+
+-- | Stationary distribution of C40 model.
+c40StatDists :: [StationaryDistribution]
+c40StatDists = map
+  V.fromList
+  [ [ 0.066026
+    , 0.00565867
+    , 0.105447
+    , 0.0440361
+    , 0.00131048
+    , 0.0711239
+    , 0.0168195
+    , 0.00390887
+    , 0.036669
+    , 0.0055316
+    , 0.00374124
+    , 0.159982
+    , 0.0176359
+    , 0.0273928
+    , 0.0231862
+    , 0.249769
+    , 0.150708
+    , 0.0065529
+    , 0.000672321
+    , 0.00382902
+    ]
+  , [ 0.0232377
+    , 0.00379875
+    , 0.353209
+    , 0.0739378
+    , 0.00240321
+    , 0.0576668
+    , 0.0315867
+    , 0.00310928
+    , 0.0259363
+    , 0.00387116
+    , 0.00173556
+    , 0.275965
+    , 0.00631169
+    , 0.0197339
+    , 0.0122683
+    , 0.0657068
+    , 0.0270484
+    , 0.00475317
+    , 0.000760289
+    , 0.00696025
+    ]
+  , [ 0.0166487
+    , 0.00366657
+    , 0.000565145
+    , 0.00133563
+    , 0.00827757
+    , 0.000889475
+    , 0.000823185
+    , 0.412937
+    , 0.00119041
+    , 0.0884689
+    , 0.0186055
+    , 0.00126222
+    , 0.001403
+    , 0.00106698
+    , 0.00125948
+    , 0.00213394
+    , 0.0162167
+    , 0.420686
+    , 0.000608205
+    , 0.00195532
+    ]
+  , [ 0.239474
+    , 0.0283812
+    , 0.00447417
+    , 0.010553
+    , 0.00559911
+    , 0.013511
+    , 0.00389298
+    , 0.0765957
+    , 0.0071093
+    , 0.0358495
+    , 0.0199496
+    , 0.0120537
+    , 0.0114266
+    , 0.00865589
+    , 0.00729013
+    , 0.0847799
+    , 0.179728
+    , 0.245468
+    , 0.0009838
+    , 0.00422407
+    ]
+  , [ 0.119461
+    , 0.0150527
+    , 0.0134273
+    , 0.0192173
+    , 0.0550467
+    , 0.0337676
+    , 0.0214746
+    , 0.0579002
+    , 0.0147261
+    , 0.144631
+    , 0.0561243
+    , 0.0294552
+    , 0.0631355
+    , 0.0301538
+    , 0.0233256
+    , 0.0925267
+    , 0.083123
+    , 0.0811758
+    , 0.0131636
+    , 0.0331118
+    ]
+  , [ 0.0567044
+    , 0.00089248
+    , 0.29555
+    , 0.379515
+    , 0.00129723
+    , 0.023047
+    , 0.0118361
+    , 0.0031182
+    , 0.0314206
+    , 0.00601375
+    , 0.00285841
+    , 0.0364734
+    , 0.0124746
+    , 0.0609517
+    , 0.0117359
+    , 0.0300335
+    , 0.0227051
+    , 0.00946396
+    , 0.000773876
+    , 0.00313438
+    ]
+  , [ 0.0179027
+    , 0.016076
+    , 0.000887041
+    , 0.00231821
+    , 0.334486
+    , 0.00398298
+    , 0.0127293
+    , 0.0404651
+    , 0.00279947
+    , 0.167614
+    , 0.0424172
+    , 0.00356977
+    , 0.00201151
+    , 0.00453955
+    , 0.00409671
+    , 0.00758416
+    , 0.00682273
+    , 0.0326045
+    , 0.0518381
+    , 0.245254
+    ]
+  , [ 0.271217
+    , 0.200383
+    , 0.0021017
+    , 0.002323
+    , 0.020299
+    , 0.0502501
+    , 0.0053728
+    , 0.0150685
+    , 0.00206463
+    , 0.0330003
+    , 0.0154811
+    , 0.0141045
+    , 0.0045351
+    , 0.00482641
+    , 0.00564808
+    , 0.17642
+    , 0.0839578
+    , 0.0741934
+    , 0.00462652
+    , 0.0141271
+    ]
+  , [ 0.0894737
+    , 0.00455383
+    , 0.0272183
+    , 0.127508
+    , 0.00565902
+    , 0.0115686
+    , 0.0215746
+    , 0.0469424
+    , 0.138205
+    , 0.0512035
+    , 0.0147657
+    , 0.0190192
+    , 0.00955465
+    , 0.116809
+    , 0.104003
+    , 0.0383954
+    , 0.0836653
+    , 0.0819556
+    , 0.00170794
+    , 0.00621813
+    ]
+  , [ 0.0495441
+    , 0.0182506
+    , 0.0143641
+    , 0.0215379
+    , 0.141805
+    , 0.01402
+    , 0.110854
+    , 0.0247066
+    , 0.0258142
+    , 0.0700288
+    , 0.0188272
+    , 0.0315864
+    , 0.0112101
+    , 0.0316504
+    , 0.0375346
+    , 0.0456094
+    , 0.0361428
+    , 0.0369178
+    , 0.0371985
+    , 0.222397
+    ]
+  , [ 0.170431
+    , 0.000974733
+    , 0.109856
+    , 0.253646
+    , 0.00133213
+    , 0.0249846
+    , 0.010139
+    , 0.00587494
+    , 0.0903324
+    , 0.0116526
+    , 0.00365127
+    , 0.0271109
+    , 0.0293614
+    , 0.09173
+    , 0.0415784
+    , 0.0561766
+    , 0.0479046
+    , 0.02033
+    , 0.000669682
+    , 0.00226373
+    ]
+  , [ 0.0162725
+    , 0.00506141
+    , 0.00101821
+    , 0.00251413
+    , 0.0376246
+    , 0.00219354
+    , 0.00299143
+    , 0.132817
+    , 0.00401204
+    , 0.490444
+    , 0.192993
+    , 0.00218762
+    , 0.00343332
+    , 0.0104414
+    , 0.00548261
+    , 0.00401221
+    , 0.0127074
+    , 0.064772
+    , 0.00321076
+    , 0.00581006
+    ]
+  , [ 0.0823766
+    , 0.00656943
+    , 0.0311745
+    , 0.0675531
+    , 0.00647179
+    , 0.0178962
+    , 0.0251144
+    , 0.0291162
+    , 0.0982302
+    , 0.0287904
+    , 0.0168023
+    , 0.059839
+    , 0.0114045
+    , 0.0686451
+    , 0.0734226
+    , 0.1303
+    , 0.182037
+    , 0.0540271
+    , 0.00227246
+    , 0.00795733
+    ]
+  , [ 0.359497
+    , 0.0251417
+    , 0.00314844
+    , 0.00649627
+    , 0.00920205
+    , 0.119468
+    , 0.00229704
+    , 0.0458767
+    , 0.00501688
+    , 0.0468054
+    , 0.0215569
+    , 0.00334215
+    , 0.0443916
+    , 0.00490143
+    , 0.00724072
+    , 0.0465271
+    , 0.0477755
+    , 0.194216
+    , 0.00245402
+    , 0.00464504
+    ]
+  , [ 0.201558
+    , 0.00323653
+    , 0.095415
+    , 0.153491
+    , 0.00256433
+    , 0.0667292
+    , 0.0155219
+    , 0.00677408
+    , 0.0547323
+    , 0.0165114
+    , 0.0060163
+    , 0.0425386
+    , 0.00919706
+    , 0.0772011
+    , 0.0430162
+    , 0.118598
+    , 0.0625473
+    , 0.0202798
+    , 0.000956551
+    , 0.003115
+    ]
+  , [ 0.104273
+    , 0.00224501
+    , 0.242407
+    , 0.177482
+    , 0.00125703
+    , 0.169782
+    , 0.0132649
+    , 0.00189295
+    , 0.0220652
+    , 0.00425426
+    , 0.00164412
+    , 0.0621646
+    , 0.0317042
+    , 0.0356499
+    , 0.0147062
+    , 0.0778636
+    , 0.0288516
+    , 0.00602502
+    , 0.00069309
+    , 0.00177419
+    ]
+  , [ 0.0781183
+    , 0.0194449
+    , 0.00415417
+    , 0.0116634
+    , 0.0262794
+    , 0.0111524
+    , 0.00635894
+    , 0.135453
+    , 0.00937298
+    , 0.245757
+    , 0.108778
+    , 0.015927
+    , 0.0055294
+    , 0.0240152
+    , 0.0111498
+    , 0.0408519
+    , 0.0860514
+    , 0.148276
+    , 0.00315476
+    , 0.00851085
+    ]
+  , [ 0.0856592
+    , 0.0136073
+    , 0.0135062
+    , 0.00786026
+    , 0.0047153
+    , 0.0245401
+    , 0.00553791
+    , 0.0100592
+    , 0.0127319
+    , 0.0103344
+    , 0.00806758
+    , 0.0441923
+    , 0.0175274
+    , 0.00925906
+    , 0.0101233
+    , 0.340648
+    , 0.357329
+    , 0.019367
+    , 0.00142431
+    , 0.00350998
+    ]
+  , [ 0.0674595
+    , 0.00216342
+    , 0.0662588
+    , 0.0865501
+    , 0.00182127
+    , 0.0368557
+    , 0.0381149
+    , 0.00332388
+    , 0.189974
+    , 0.009384
+    , 0.00394874
+    , 0.116311
+    , 0.0151208
+    , 0.093936
+    , 0.116173
+    , 0.0842204
+    , 0.0565954
+    , 0.00645142
+    , 0.00071873
+    , 0.00461894
+    ]
+  , [ 0.0572262
+    , 0.00153015
+    , 0.179393
+    , 0.199226
+    , 0.00137018
+    , 0.0316472
+    , 0.0291392
+    , 0.00458046
+    , 0.101562
+    , 0.010074
+    , 0.00402046
+    , 0.108388
+    , 0.00636741
+    , 0.0903669
+    , 0.0494724
+    , 0.0621143
+    , 0.0496102
+    , 0.00859413
+    , 0.000666929
+    , 0.00464976
+    ]
+  , [ 0.00360202
+    , 0.00454848
+    , 0.00208716
+    , 0.00178577
+    , 0.0855715
+    , 0.00563916
+    , 0.00649688
+    , 0.00292929
+    , 0.00104198
+    , 0.0232635
+    , 0.00445923
+    , 0.00134555
+    , 0.0024992
+    , 0.00327181
+    , 0.0102713
+    , 0.00306718
+    , 0.00259003
+    , 0.00586684
+    , 0.761782
+    , 0.067881
+    ]
+  , [ 0.203202
+    , 0.00981316
+    , 0.0135012
+    , 0.00838182
+    , 0.00196196
+    , 0.618489
+    , 0.00277479
+    , 0.00118285
+    , 0.00445989
+    , 0.00398268
+    , 0.00206318
+    , 0.0143744
+    , 0.00858704
+    , 0.00445146
+    , 0.00838957
+    , 0.073992
+    , 0.0108922
+    , 0.00607691
+    , 0.00186061
+    , 0.00156387
+    ]
+  , [ 0.00508988
+    , 0.00617765
+    , 0.00161262
+    , 0.00120404
+    , 0.356313
+    , 0.00163342
+    , 0.0393461
+    , 0.00590888
+    , 0.00137137
+    , 0.0249344
+    , 0.00497952
+    , 0.0057093
+    , 0.00141364
+    , 0.00246931
+    , 0.00287408
+    , 0.00595277
+    , 0.00365368
+    , 0.00819341
+    , 0.0357987
+    , 0.485365
+    ]
+  , [ 0.0403336
+    , 0.00815495
+    , 0.00982186
+    , 0.0375407
+    , 0.0119141
+    , 0.00479344
+    , 0.0176736
+    , 0.189342
+    , 0.0607377
+    , 0.105186
+    , 0.03056
+    , 0.0216052
+    , 0.00775506
+    , 0.0383639
+    , 0.0540186
+    , 0.025711
+    , 0.100991
+    , 0.221091
+    , 0.002878
+    , 0.0115277
+    ]
+  , [ 0.0790086
+    , 0.00249479
+    , 0.0546012
+    , 0.199788
+    , 0.00237734
+    , 0.0192656
+    , 0.02707
+    , 0.00756675
+    , 0.155311
+    , 0.0254542
+    , 0.00980244
+    , 0.0309384
+    , 0.00566407
+    , 0.184338
+    , 0.106544
+    , 0.0332371
+    , 0.0359575
+    , 0.0145306
+    , 0.00116828
+    , 0.00488208
+    ]
+  , [ 0.0722241
+    , 0.00647553
+    , 0.119488
+    , 0.134589
+    , 0.0348233
+    , 0.0287815
+    , 0.0699011
+    , 0.0173589
+    , 0.0490342
+    , 0.051987
+    , 0.0154411
+    , 0.067893
+    , 0.0145597
+    , 0.070897
+    , 0.0489728
+    , 0.058958
+    , 0.0425973
+    , 0.0317884
+    , 0.00879138
+    , 0.0554387
+    ]
+  , [ 0.108584
+    , 0.00125026
+    , 0.152967
+    , 0.166485
+    , 0.00145535
+    , 0.0336098
+    , 0.0134902
+    , 0.00388218
+    , 0.0576227
+    , 0.00898614
+    , 0.0024339
+    , 0.0441956
+    , 0.19901
+    , 0.0405398
+    , 0.020645
+    , 0.084675
+    , 0.0454715
+    , 0.0113416
+    , 0.000590283
+    , 0.00276502
+    ]
+  , [ 0.0309526
+    , 0.0065594
+    , 0.00823521
+    , 0.0291974
+    , 0.00368916
+    , 0.0154206
+    , 0.0310385
+    , 0.00982516
+    , 0.306263
+    , 0.02379
+    , 0.00970717
+    , 0.0301337
+    , 0.00950291
+    , 0.0832608
+    , 0.319589
+    , 0.0295285
+    , 0.0303052
+    , 0.0133037
+    , 0.00281253
+    , 0.00688506
+    ]
+  , [ 0.00989537
+    , 0.00282767
+    , 0.000374823
+    , 0.00091821
+    , 0.0298607
+    , 0.000699707
+    , 0.00104195
+    , 0.311504
+    , 0.00139605
+    , 0.375039
+    , 0.0474451
+    , 0.000730793
+    , 0.00252963
+    , 0.0017337
+    , 0.00196045
+    , 0.0014628
+    , 0.0075739
+    , 0.1973
+    , 0.00167998
+    , 0.00402599
+    ]
+  , [ 0.116321
+    , 0.00347923
+    , 0.0731918
+    , 0.138088
+    , 0.00941177
+    , 0.0193193
+    , 0.0160241
+    , 0.0712243
+    , 0.035512
+    , 0.0771474
+    , 0.0242841
+    , 0.0250164
+    , 0.0508927
+    , 0.0586677
+    , 0.0273321
+    , 0.047556
+    , 0.0726552
+    , 0.123571
+    , 0.00268927
+    , 0.0076166
+    ]
+  , [ 0.128522
+    , 0.0172929
+    , 0.040275
+    , 0.0250692
+    , 0.0199118
+    , 0.112703
+    , 0.0606981
+    , 0.010935
+    , 0.028875
+    , 0.0258416
+    , 0.0167593
+    , 0.117984
+    , 0.0180675
+    , 0.0439706
+    , 0.0373073
+    , 0.174149
+    , 0.0648968
+    , 0.0182067
+    , 0.0063575
+    , 0.0321772
+    ]
+  , [ 0.0372287
+    , 0.014494
+    , 0.00237032
+    , 0.00485851
+    , 0.146377
+    , 0.00464339
+    , 0.0186795
+    , 0.182046
+    , 0.00581985
+    , 0.17801
+    , 0.0371334
+    , 0.00533773
+    , 0.00485386
+    , 0.00790971
+    , 0.0094528
+    , 0.0103571
+    , 0.0284162
+    , 0.184992
+    , 0.0211294
+    , 0.0958905
+    ]
+  , [ 0.0535644
+    , 0.00962562
+    , 0.0113537
+    , 0.0391699
+    , 0.0264214
+    , 0.0120279
+    , 0.0384888
+    , 0.0522748
+    , 0.0996038
+    , 0.189239
+    , 0.0712219
+    , 0.0239173
+    , 0.00837206
+    , 0.0928585
+    , 0.11598
+    , 0.0299114
+    , 0.0389485
+    , 0.0500948
+    , 0.0104232
+    , 0.026503
+    ]
+  , [ 0.133242
+    , 0.0246514
+    , 0.00127392
+    , 0.00404615
+    , 0.0156995
+    , 0.00891392
+    , 0.00158647
+    , 0.197128
+    , 0.00237132
+    , 0.125129
+    , 0.0286947
+    , 0.0022705
+    , 0.0118846
+    , 0.00308435
+    , 0.00331477
+    , 0.0171462
+    , 0.0563298
+    , 0.356621
+    , 0.00173418
+    , 0.00487784
+    ]
+  , [ 0.149866
+    , 0.00354374
+    , 0.0280355
+    , 0.0435381
+    , 0.00475339
+    , 0.0311113
+    , 0.0140626
+    , 0.0101953
+    , 0.0393125
+    , 0.0251434
+    , 0.00515483
+    , 0.0176453
+    , 0.39238
+    , 0.0348151
+    , 0.0326607
+    , 0.0874497
+    , 0.0473307
+    , 0.0271597
+    , 0.00152152
+    , 0.00432083
+    ]
+  , [ 0.421437
+    , 0.018761
+    , 0.00733051
+    , 0.00868378
+    , 0.00271561
+    , 0.0902333
+    , 0.0030262
+    , 0.00393628
+    , 0.00515087
+    , 0.00471933
+    , 0.00383066
+    , 0.012159
+    , 0.020894
+    , 0.00727486
+    , 0.0061426
+    , 0.290119
+    , 0.0651922
+    , 0.0252211
+    , 0.000810824
+    , 0.00236228
+    ]
+  , [ 0.177071
+    , 0.00783489
+    , 0.02265
+    , 0.0509767
+    , 0.00405142
+    , 0.089739
+    , 0.0220667
+    , 0.00595198
+    , 0.125769
+    , 0.020537
+    , 0.00929825
+    , 0.0311657
+    , 0.0264088
+    , 0.0752471
+    , 0.133278
+    , 0.116959
+    , 0.0565567
+    , 0.0165087
+    , 0.00299471
+    , 0.00493467
+    ]
+  , [ 0.0293984
+    , 0.00317291
+    , 0.109971
+    , 0.046427
+    , 0.00150396
+    , 0.422242
+    , 0.0272495
+    , 0.000799733
+    , 0.0622314
+    , 0.00376343
+    , 0.00166571
+    , 0.148362
+    , 0.00564818
+    , 0.0388688
+    , 0.0370902
+    , 0.0472252
+    , 0.0086569
+    , 0.00203639
+    , 0.000917602
+    , 0.00276931
+    ]
+  , [ 0.0265779
+    , 0.0101369
+    , 0.0280314
+    , 0.0269057
+    , 0.0276961
+    , 0.0173377
+    , 0.281513
+    , 0.0064647
+    , 0.0474749
+    , 0.026821
+    , 0.00723753
+    , 0.13186
+    , 0.0083015
+    , 0.0989711
+    , 0.0791105
+    , 0.0426277
+    , 0.0259043
+    , 0.0100147
+    , 0.00785289
+    , 0.0891598
+    ]
+  , [ 0.00960965
+    , 0.00773017
+    , 0.000633186
+    , 0.00104719
+    , 0.263017
+    , 0.00202274
+    , 0.00390014
+    , 0.0733098
+    , 0.00149315
+    , 0.445169
+    , 0.0732575
+    , 0.00131044
+    , 0.00427681
+    , 0.00338994
+    , 0.00271362
+    , 0.00361174
+    , 0.00579284
+    , 0.0425173
+    , 0.0181276
+    , 0.0370698
+    ]
+  ]
+
+-- | Weights of C40 model.
+c40Weights :: [Double]
+c40Weights =
+  [ 0.0223854
+  , 0.0338892
+  , 0.0577169
+  , 0.0252416
+  , 0.0108608
+  , 0.0462374
+  , 0.0102293
+  , 0.0147524
+  , 0.0143161
+  , 0.0182303
+  , 0.0204025
+  , 0.0425505
+  , 0.0248627
+  , 0.0105893
+  , 0.0188239
+  , 0.00866634
+  , 0.0148496
+  , 0.0343037
+  , 0.0225335
+  , 0.0174069
+  , 0.0112208
+  , 0.0443532
+  , 0.0392573
+  , 0.0196757
+  , 0.028769
+  , 0.0114441
+  , 0.0112339
+  , 0.0582694
+  , 0.0444272
+  , 0.0112011
+  , 0.0145176
+  , 0.0114629
+  , 0.0239628
+  , 0.0266266
+  , 0.0481201
+  , 0.0371147
+  , 0.0160477
+  , 0.0237249
+  , 0.0235226
+  , 0.0261998
+  ]
+
+-- | Stationary distribution of C50 model.
+c50StatDists :: [StationaryDistribution]
+c50StatDists = map
+  V.fromList
+  [ [ 0.115682
+    , 0.00212412
+    , 0.125699
+    , 0.0919063
+    , 0.0016175
+    , 0.0391977
+    , 0.0108596
+    , 0.00344834
+    , 0.0344439
+    , 0.0125587
+    , 0.00467132
+    , 0.0530851
+    , 0.206661
+    , 0.0264814
+    , 0.0147638
+    , 0.154493
+    , 0.0841319
+    , 0.0134754
+    , 0.000392551
+    , 0.00430762
+    ]
+  , [ 0.0983768
+    , 0.00160659
+    , 0.0456633
+    , 0.0935028
+    , 0.00112009
+    , 0.0251388
+    , 0.0191777
+    , 0.00367483
+    , 0.151407
+    , 0.0115555
+    , 0.00258422
+    , 0.0266318
+    , 0.229718
+    , 0.0694385
+    , 0.0855866
+    , 0.0696565
+    , 0.0498854
+    , 0.0123983
+    , 0.00069296
+    , 0.00218381
+    ]
+  , [ 0.0214598
+    , 0.00446298
+    , 0.000555089
+    , 0.00135258
+    , 0.00855351
+    , 0.00112246
+    , 0.000813505
+    , 0.399631
+    , 0.00128242
+    , 0.0868331
+    , 0.0170323
+    , 0.00117488
+    , 0.00183519
+    , 0.00101872
+    , 0.00142423
+    , 0.00233511
+    , 0.0161891
+    , 0.430205
+    , 0.00061736
+    , 0.00210206
+    ]
+  , [ 0.117155
+    , 0.032654
+    , 0.00620066
+    , 0.00998032
+    , 0.0657132
+    , 0.0333659
+    , 0.0134621
+    , 0.0557335
+    , 0.00794829
+    , 0.199356
+    , 0.0938018
+    , 0.0221831
+    , 0.0115415
+    , 0.0204903
+    , 0.0146873
+    , 0.0842555
+    , 0.0920314
+    , 0.0798031
+    , 0.0127314
+    , 0.0269048
+    ]
+  , [ 0.0371284
+    , 0.0131607
+    , 0.00255462
+    , 0.00465054
+    , 0.156922
+    , 0.00416133
+    , 0.019977
+    , 0.178808
+    , 0.00498614
+    , 0.165159
+    , 0.0352649
+    , 0.0057612
+    , 0.00512406
+    , 0.00679862
+    , 0.00826841
+    , 0.0102949
+    , 0.0275498
+    , 0.181807
+    , 0.0221255
+    , 0.109498
+    ]
+  , [ 0.0540087
+    , 0.000836323
+    , 0.306245
+    , 0.38187
+    , 0.00111469
+    , 0.0245756
+    , 0.0116353
+    , 0.00254509
+    , 0.030937
+    , 0.00536416
+    , 0.00256903
+    , 0.0359123
+    , 0.0122515
+    , 0.0586791
+    , 0.0115134
+    , 0.0277199
+    , 0.020314
+    , 0.00828799
+    , 0.000720693
+    , 0.00290032
+    ]
+  , [ 0.0404572
+    , 0.028652
+    , 0.00495693
+    , 0.0068813
+    , 0.242849
+    , 0.0103569
+    , 0.0318377
+    , 0.0329142
+    , 0.0105561
+    , 0.143431
+    , 0.0485779
+    , 0.0105988
+    , 0.00489299
+    , 0.0118557
+    , 0.0126873
+    , 0.0229136
+    , 0.0212457
+    , 0.0349069
+    , 0.0593874
+    , 0.220042
+    ]
+  , [ 0.319667
+    , 0.138968
+    , 0.00144847
+    , 0.00200138
+    , 0.00997903
+    , 0.0503464
+    , 0.00296588
+    , 0.0182219
+    , 0.00202126
+    , 0.0260477
+    , 0.0136422
+    , 0.00936868
+    , 0.00591365
+    , 0.00358722
+    , 0.00435407
+    , 0.1656
+    , 0.118413
+    , 0.0996664
+    , 0.00164228
+    , 0.00614589
+    ]
+  , [ 0.0977328
+    , 0.00251083
+    , 0.0724816
+    , 0.197027
+    , 0.00556062
+    , 0.0117997
+    , 0.0154288
+    , 0.0563751
+    , 0.0613631
+    , 0.047368
+    , 0.0159721
+    , 0.0241106
+    , 0.0149
+    , 0.0909736
+    , 0.034432
+    , 0.0408092
+    , 0.0929289
+    , 0.111482
+    , 0.00122744
+    , 0.00551621
+    ]
+  , [ 0.0195453
+    , 0.0107627
+    , 0.0127492
+    , 0.011794
+    , 0.14032
+    , 0.0061666
+    , 0.215761
+    , 0.00826718
+    , 0.0118897
+    , 0.0328258
+    , 0.00664433
+    , 0.0423533
+    , 0.00528472
+    , 0.0258824
+    , 0.024497
+    , 0.0203711
+    , 0.0124449
+    , 0.0133889
+    , 0.0330587
+    , 0.345993
+    ]
+  , [ 0.185338
+    , 0.00185224
+    , 0.161345
+    , 0.234878
+    , 0.00192286
+    , 0.054278
+    , 0.0109591
+    , 0.00550122
+    , 0.0382027
+    , 0.00925008
+    , 0.00343293
+    , 0.033406
+    , 0.0233824
+    , 0.0551124
+    , 0.0201268
+    , 0.0884267
+    , 0.051789
+    , 0.0177494
+    , 0.000835994
+    , 0.00221142
+    ]
+  , [ 0.0143603
+    , 0.0036047
+    , 0.000411253
+    , 0.00108887
+    , 0.0196479
+    , 0.00187385
+    , 0.000991664
+    , 0.285685
+    , 0.00213672
+    , 0.317288
+    , 0.150556
+    , 0.00155703
+    , 0.00122034
+    , 0.0028111
+    , 0.00194519
+    , 0.00344669
+    , 0.0196686
+    , 0.167294
+    , 0.000843478
+    , 0.00356936
+    ]
+  , [ 0.150577
+    , 0.00957632
+    , 0.0227565
+    , 0.0358641
+    , 0.0104881
+    , 0.0285062
+    , 0.0171219
+    , 0.0577109
+    , 0.0276149
+    , 0.0531781
+    , 0.0298859
+    , 0.0514957
+    , 0.0243637
+    , 0.0354202
+    , 0.0272841
+    , 0.132633
+    , 0.169554
+    , 0.104387
+    , 0.00219421
+    , 0.00938724
+    ]
+  , [ 0.277615
+    , 0.0280749
+    , 0.00194439
+    , 0.00537302
+    , 0.0070772
+    , 0.0234861
+    , 0.0012257
+    , 0.0949678
+    , 0.00308357
+    , 0.0474515
+    , 0.0189616
+    , 0.0034483
+    , 0.0134815
+    , 0.00374076
+    , 0.00354151
+    , 0.0423818
+    , 0.0932708
+    , 0.326207
+    , 0.000963513
+    , 0.00370386
+    ]
+  , [ 0.205879
+    , 0.00249091
+    , 0.075426
+    , 0.161651
+    , 0.00210732
+    , 0.0463391
+    , 0.0159993
+    , 0.00515537
+    , 0.0913036
+    , 0.0166911
+    , 0.00536596
+    , 0.0366042
+    , 0.00849072
+    , 0.0973331
+    , 0.0696431
+    , 0.088244
+    , 0.0501877
+    , 0.0172747
+    , 0.000776174
+    , 0.0030381
+    ]
+  , [ 0.0704473
+    , 0.00149732
+    , 0.187469
+    , 0.208434
+    , 0.0013217
+    , 0.0409359
+    , 0.0247326
+    , 0.00339884
+    , 0.0739754
+    , 0.00761491
+    , 0.00270559
+    , 0.0965448
+    , 0.00673196
+    , 0.0820493
+    , 0.0355811
+    , 0.0832004
+    , 0.0610002
+    , 0.00788473
+    , 0.000646918
+    , 0.00382803
+    ]
+  , [ 0.108767
+    , 0.00735776
+    , 0.0100122
+    , 0.0249269
+    , 0.015562
+    , 0.0114116
+    , 0.00730171
+    , 0.0923916
+    , 0.0138538
+    , 0.112308
+    , 0.0251594
+    , 0.00831075
+    , 0.259979
+    , 0.0187962
+    , 0.0142911
+    , 0.0329858
+    , 0.0608007
+    , 0.162244
+    , 0.0049709
+    , 0.00857003
+    ]
+  , [ 0.109878
+    , 0.0295589
+    , 0.000867374
+    , 0.00267084
+    , 0.028604
+    , 0.0101436
+    , 0.00159952
+    , 0.171472
+    , 0.0015037
+    , 0.241889
+    , 0.0488425
+    , 0.00201796
+    , 0.00631863
+    , 0.00393786
+    , 0.00336164
+    , 0.0148413
+    , 0.0393773
+    , 0.273667
+    , 0.00359303
+    , 0.00585493
+    ]
+  , [ 0.058736
+    , 0.00692528
+    , 0.0144651
+    , 0.0412403
+    , 0.0154694
+    , 0.015436
+    , 0.0243546
+    , 0.0388984
+    , 0.0996366
+    , 0.207192
+    , 0.103832
+    , 0.0289715
+    , 0.00833815
+    , 0.108218
+    , 0.0976056
+    , 0.0350037
+    , 0.0432645
+    , 0.0338957
+    , 0.00652556
+    , 0.0119916
+    ]
+  , [ 0.0642736
+    , 0.00525071
+    , 0.144305
+    , 0.153274
+    , 0.0286093
+    , 0.0265312
+    , 0.0545105
+    , 0.0231701
+    , 0.0452879
+    , 0.058794
+    , 0.0192273
+    , 0.071063
+    , 0.0146855
+    , 0.066931
+    , 0.0405954
+    , 0.054046
+    , 0.043602
+    , 0.0350962
+    , 0.00655203
+    , 0.0441953
+    ]
+  , [ 0.00487716
+    , 0.00503139
+    , 0.00209095
+    , 0.00192293
+    , 0.0983777
+    , 0.00615619
+    , 0.00725617
+    , 0.00400789
+    , 0.000993075
+    , 0.0277171
+    , 0.00537714
+    , 0.00145717
+    , 0.0029039
+    , 0.00350461
+    , 0.0112195
+    , 0.00329284
+    , 0.00295187
+    , 0.00708726
+    , 0.724652
+    , 0.0791231
+    ]
+  , [ 0.0552756
+    , 0.0115894
+    , 0.00846155
+    , 0.0432312
+    , 0.00961795
+    , 0.0074182
+    , 0.0218432
+    , 0.0843826
+    , 0.163327
+    , 0.0631707
+    , 0.0228359
+    , 0.0221225
+    , 0.00652522
+    , 0.0639538
+    , 0.146077
+    , 0.0387464
+    , 0.100713
+    , 0.118118
+    , 0.00298298
+    , 0.00960875
+    ]
+  , [ 0.00449551
+    , 0.00619902
+    , 0.000890609
+    , 0.000674178
+    , 0.400884
+    , 0.0013356
+    , 0.0223834
+    , 0.00805107
+    , 0.00105813
+    , 0.0341606
+    , 0.00701178
+    , 0.00318917
+    , 0.00130624
+    , 0.00157564
+    , 0.00181707
+    , 0.00502515
+    , 0.00337803
+    , 0.00946203
+    , 0.0345278
+    , 0.452575
+    ]
+  , [ 0.0505469
+    , 0.00768183
+    , 0.0101983
+    , 0.0470721
+    , 0.0160596
+    , 0.00517598
+    , 0.0176387
+    , 0.169463
+    , 0.0497501
+    , 0.209444
+    , 0.0474166
+    , 0.0132404
+    , 0.00844474
+    , 0.053753
+    , 0.051076
+    , 0.0149657
+    , 0.03846
+    , 0.172926
+    , 0.00437246
+    , 0.0123139
+    ]
+  , [ 0.0749936
+    , 0.0124353
+    , 0.0203869
+    , 0.0100161
+    , 0.0038092
+    , 0.0270453
+    , 0.00581932
+    , 0.00743392
+    , 0.014732
+    , 0.00838354
+    , 0.00640172
+    , 0.0530316
+    , 0.0176075
+    , 0.0096947
+    , 0.0117746
+    , 0.3482
+    , 0.348235
+    , 0.0157071
+    , 0.00137596
+    , 0.00291601
+    ]
+  , [ 0.0569785
+    , 0.00176591
+    , 0.102737
+    , 0.106157
+    , 0.00132179
+    , 0.0360979
+    , 0.034465
+    , 0.00311879
+    , 0.185459
+    , 0.00858711
+    , 0.00431374
+    , 0.139374
+    , 0.00855798
+    , 0.0898676
+    , 0.101042
+    , 0.0669467
+    , 0.0422839
+    , 0.00552428
+    , 0.000686497
+    , 0.00471478
+    ]
+  , [ 0.0746973
+    , 0.00394557
+    , 0.0423454
+    , 0.0906599
+    , 0.00363883
+    , 0.0183504
+    , 0.0229406
+    , 0.0156166
+    , 0.12297
+    , 0.0167059
+    , 0.00901115
+    , 0.0672502
+    , 0.0127747
+    , 0.0811334
+    , 0.0755385
+    , 0.132886
+    , 0.170553
+    , 0.0324157
+    , 0.00152093
+    , 0.00504616
+    ]
+  , [ 0.17313
+    , 0.00938612
+    , 0.0203504
+    , 0.0387504
+    , 0.00448721
+    , 0.0867075
+    , 0.0227177
+    , 0.00492238
+    , 0.125544
+    , 0.0156727
+    , 0.00787132
+    , 0.0400476
+    , 0.0180405
+    , 0.0680443
+    , 0.133335
+    , 0.142136
+    , 0.0670614
+    , 0.0136107
+    , 0.00287027
+    , 0.00531475
+    ]
+  , [ 0.00751784
+    , 0.00212117
+    , 0.000341917
+    , 0.000667876
+    , 0.0310677
+    , 0.000466913
+    , 0.000898937
+    , 0.320302
+    , 0.00103903
+    , 0.384419
+    , 0.0335748
+    , 0.000602706
+    , 0.00243131
+    , 0.00137426
+    , 0.00152778
+    , 0.00115498
+    , 0.00552329
+    , 0.199295
+    , 0.00172716
+    , 0.00394622
+    ]
+  , [ 0.113459
+    , 0.0281671
+    , 0.0268294
+    , 0.0283293
+    , 0.0928796
+    , 0.0494616
+    , 0.0733971
+    , 0.0152335
+    , 0.0176739
+    , 0.037425
+    , 0.0140126
+    , 0.0539481
+    , 0.0259048
+    , 0.0303861
+    , 0.0259068
+    , 0.121621
+    , 0.0621544
+    , 0.0350518
+    , 0.0240853
+    , 0.124074
+    ]
+  , [ 0.0810974
+    , 0.00899714
+    , 0.0930492
+    , 0.0372909
+    , 0.002713
+    , 0.0907986
+    , 0.0275326
+    , 0.00533957
+    , 0.0362449
+    , 0.00831441
+    , 0.00615441
+    , 0.177093
+    , 0.0120848
+    , 0.0316411
+    , 0.025247
+    , 0.233557
+    , 0.106302
+    , 0.00814021
+    , 0.000950692
+    , 0.00745168
+    ]
+  , [ 0.00757098
+    , 0.00716117
+    , 0.00049456
+    , 0.000891326
+    , 0.297029
+    , 0.00155605
+    , 0.00342729
+    , 0.0711141
+    , 0.00107067
+    , 0.416918
+    , 0.0635143
+    , 0.000864035
+    , 0.00349893
+    , 0.00251506
+    , 0.00186372
+    , 0.00271598
+    , 0.00424124
+    , 0.041488
+    , 0.0202374
+    , 0.0518279
+    ]
+  , [ 0.086899
+    , 0.00542266
+    , 0.0274343
+    , 0.117345
+    , 0.00568342
+    , 0.0162895
+    , 0.0386176
+    , 0.0182492
+    , 0.149526
+    , 0.048245
+    , 0.0150062
+    , 0.0265186
+    , 0.00577334
+    , 0.159013
+    , 0.149227
+    , 0.0416278
+    , 0.0492401
+    , 0.0283951
+    , 0.00272523
+    , 0.00876225
+    ]
+  , [ 0.0501736
+    , 0.0113806
+    , 0.00768113
+    , 0.0191841
+    , 0.0119036
+    , 0.00521331
+    , 0.00988204
+    , 0.203482
+    , 0.0206446
+    , 0.0870652
+    , 0.036001
+    , 0.0197961
+    , 0.0061624
+    , 0.0180415
+    , 0.0178215
+    , 0.0399964
+    , 0.162255
+    , 0.262373
+    , 0.00172457
+    , 0.00921833
+    ]
+  , [ 0.177098
+    , 0.00357587
+    , 0.0740854
+    , 0.0713923
+    , 0.00385864
+    , 0.211235
+    , 0.0161904
+    , 0.0040472
+    , 0.0370753
+    , 0.00826202
+    , 0.00369757
+    , 0.0494737
+    , 0.0543871
+    , 0.0396583
+    , 0.0340392
+    , 0.140615
+    , 0.0532238
+    , 0.0108131
+    , 0.00212448
+    , 0.00514764
+    ]
+  , [ 0.242384
+    , 0.0115188
+    , 0.00720908
+    , 0.00544261
+    , 0.00229719
+    , 0.593273
+    , 0.00205723
+    , 0.00208173
+    , 0.00287156
+    , 0.00491
+    , 0.00271204
+    , 0.00899551
+    , 0.00763059
+    , 0.00285962
+    , 0.00600369
+    , 0.0738385
+    , 0.0108329
+    , 0.00968775
+    , 0.00178961
+    , 0.00160391
+    ]
+  , [ 0.032912
+    , 0.00319267
+    , 0.143899
+    , 0.0532755
+    , 0.00166462
+    , 0.463509
+    , 0.0175283
+    , 0.000876108
+    , 0.0317056
+    , 0.00297349
+    , 0.0012156
+    , 0.131603
+    , 0.00688601
+    , 0.0251373
+    , 0.0184844
+    , 0.0491059
+    , 0.00984294
+    , 0.00239178
+    , 0.0008917
+    , 0.00290456
+    ]
+  , [ 0.0388306
+    , 0.00489943
+    , 0.0491655
+    , 0.0413874
+    , 0.00170354
+    , 0.345044
+    , 0.0421499
+    , 0.00103798
+    , 0.123725
+    , 0.00726049
+    , 0.00335164
+    , 0.119727
+    , 0.00562115
+    , 0.0664068
+    , 0.0881106
+    , 0.0460192
+    , 0.00791813
+    , 0.0020819
+    , 0.00195492
+    , 0.00360516
+    ]
+  , [ 0.0373301
+    , 0.00916334
+    , 0.0396965
+    , 0.0362168
+    , 0.0144959
+    , 0.0269081
+    , 0.220512
+    , 0.00638711
+    , 0.0634517
+    , 0.0225147
+    , 0.00718608
+    , 0.152708
+    , 0.00995802
+    , 0.108449
+    , 0.0882553
+    , 0.0609295
+    , 0.0332848
+    , 0.0105312
+    , 0.00429315
+    , 0.047729
+    ]
+  , [ 0.0171508
+    , 0.00565843
+    , 0.00111564
+    , 0.00268175
+    , 0.0490847
+    , 0.00219974
+    , 0.00370226
+    , 0.116938
+    , 0.00407925
+    , 0.500942
+    , 0.1832
+    , 0.00280387
+    , 0.00400697
+    , 0.0115255
+    , 0.00613355
+    , 0.00539456
+    , 0.0140434
+    , 0.0579479
+    , 0.00419195
+    , 0.00719895
+    ]
+  , [ 0.0238117
+    , 0.00329378
+    , 0.370777
+    , 0.0831676
+    , 0.0022275
+    , 0.053433
+    , 0.0290274
+    , 0.00288609
+    , 0.0258098
+    , 0.00370314
+    , 0.00159506
+    , 0.259554
+    , 0.00668902
+    , 0.0201877
+    , 0.0117854
+    , 0.0626213
+    , 0.0278627
+    , 0.00464381
+    , 0.000688992
+    , 0.0062349
+    ]
+  , [ 0.209736
+    , 0.0105937
+    , 0.0311812
+    , 0.0613839
+    , 0.00991105
+    , 0.0855144
+    , 0.0226071
+    , 0.0296058
+    , 0.0455281
+    , 0.0792591
+    , 0.0306389
+    , 0.019447
+    , 0.0213982
+    , 0.0610672
+    , 0.0588191
+    , 0.0820738
+    , 0.0527883
+    , 0.0722389
+    , 0.00513
+    , 0.0110785
+    ]
+  , [ 0.0295833
+    , 0.00588894
+    , 0.00852018
+    , 0.0296344
+    , 0.00323424
+    , 0.0154495
+    , 0.02992
+    , 0.00752729
+    , 0.317117
+    , 0.0212988
+    , 0.00874154
+    , 0.0312424
+    , 0.00843308
+    , 0.0831654
+    , 0.323587
+    , 0.0294177
+    , 0.0283085
+    , 0.0100345
+    , 0.00257807
+    , 0.00631797
+    ]
+  , [ 0.0937098
+    , 0.00289961
+    , 0.0255803
+    , 0.0577481
+    , 0.0140839
+    , 0.0182984
+    , 0.0300827
+    , 0.0312422
+    , 0.0867966
+    , 0.067914
+    , 0.01767
+    , 0.0206426
+    , 0.213942
+    , 0.0611154
+    , 0.0902988
+    , 0.0526724
+    , 0.0464314
+    , 0.0509513
+    , 0.00365078
+    , 0.01427
+    ]
+  , [ 0.419507
+    , 0.0176715
+    , 0.00719436
+    , 0.00880545
+    , 0.00285112
+    , 0.0865515
+    , 0.00330323
+    , 0.00419601
+    , 0.00503365
+    , 0.0048203
+    , 0.00393323
+    , 0.012443
+    , 0.0192167
+    , 0.00750218
+    , 0.00609116
+    , 0.295973
+    , 0.0660748
+    , 0.0253174
+    , 0.000942289
+    , 0.00257126
+    ]
+  , [ 0.0368106
+    , 0.0124259
+    , 0.0102859
+    , 0.0343205
+    , 0.0759532
+    , 0.00772969
+    , 0.0938663
+    , 0.0458547
+    , 0.0701169
+    , 0.133403
+    , 0.031916
+    , 0.0265402
+    , 0.00749485
+    , 0.0673302
+    , 0.10388
+    , 0.0271625
+    , 0.0353789
+    , 0.0485031
+    , 0.0254607
+    , 0.105568
+    ]
+  , [ 0.0665479
+    , 0.00185956
+    , 0.183575
+    , 0.149215
+    , 0.00127224
+    , 0.0634659
+    , 0.019684
+    , 0.00262142
+    , 0.0655694
+    , 0.00750609
+    , 0.00151282
+    , 0.0699101
+    , 0.182105
+    , 0.0446839
+    , 0.0292035
+    , 0.075452
+    , 0.0278833
+    , 0.00484561
+    , 0.000723776
+    , 0.00236318
+    ]
+  , [ 0.16002
+    , 0.00397537
+    , 0.019682
+    , 0.0286161
+    , 0.00458768
+    , 0.0326662
+    , 0.0114325
+    , 0.00722291
+    , 0.0232558
+    , 0.0202542
+    , 0.00379358
+    , 0.0142832
+    , 0.460797
+    , 0.0260458
+    , 0.0217875
+    , 0.0913633
+    , 0.0427326
+    , 0.0227118
+    , 0.0012566
+    , 0.0035159
+    ]
+  , [ 0.0843584
+    , 0.00129715
+    , 0.0847585
+    , 0.260552
+    , 0.00143564
+    , 0.0191268
+    , 0.0174708
+    , 0.00556223
+    , 0.144172
+    , 0.014456
+    , 0.00550323
+    , 0.0336163
+    , 0.00724868
+    , 0.160704
+    , 0.0742581
+    , 0.0323411
+    , 0.0355032
+    , 0.0136662
+    , 0.000760206
+    , 0.00320994
+    ]
+  , [ 0.152149
+    , 0.000925399
+    , 0.116471
+    , 0.220438
+    , 0.00150071
+    , 0.0172039
+    , 0.0095692
+    , 0.00747151
+    , 0.0529323
+    , 0.0148756
+    , 0.00356173
+    , 0.0157411
+    , 0.217335
+    , 0.0489135
+    , 0.0171707
+    , 0.044102
+    , 0.0323715
+    , 0.023915
+    , 0.000908902
+    , 0.00244332
+    ]
+  ]
+
+-- | Weights of C50 model.
+c50Weights :: [Double]
+c50Weights =
+  [ 0.00509464
+  , 0.00753314
+  , 0.0595801
+  , 0.0100458
+  , 0.0109109
+  , 0.0427412
+  , 0.00632106
+  , 0.0192362
+  , 0.0119168
+  , 0.0154209
+  , 0.0148037
+  , 0.014293
+  , 0.0164064
+  , 0.0272538
+  , 0.0178737
+  , 0.0125183
+  , 0.00698661
+  , 0.0140027
+  , 0.0140399
+  , 0.0109043
+  , 0.011579
+  , 0.0138661
+  , 0.0377329
+  , 0.0118586
+  , 0.0356688
+  , 0.0161327
+  , 0.0200601
+  , 0.0133087
+  , 0.0357641
+  , 0.0119353
+  , 0.0241183
+  , 0.0243098
+  , 0.0178039
+  , 0.0200988
+  , 0.00579569
+  , 0.0397441
+  , 0.0240799
+  , 0.00868054
+  , 0.0239822
+  , 0.042803
+  , 0.0335193
+  , 0.00636191
+  , 0.0547546
+  , 0.00544598
+  , 0.0354219
+  , 0.0120158
+  , 0.0047506
+  , 0.036392
+  , 0.0270346
+  , 0.00709747
+  ]
+
+-- | Stationary distribution of C60 model.
+c60StatDists :: [StationaryDistribution]
+c60StatDists = map
+  V.fromList
+  [ [ 0.153436
+    , 0.00473066
+    , 0.0546757
+    , 0.0529324
+    , 0.00355543
+    , 0.110378
+    , 0.017448
+    , 0.00503439
+    , 0.0603929
+    , 0.0130294
+    , 0.00755506
+    , 0.0796727
+    , 0.0249524
+    , 0.0514333
+    , 0.0444389
+    , 0.202963
+    , 0.0957668
+    , 0.0101809
+    , 0.00144445
+    , 0.00598003
+    ]
+  , [ 0.0281985
+    , 0.00195035
+    , 0.00915493
+    , 0.038853
+    , 0.00159193
+    , 0.00840283
+    , 0.0155385
+    , 0.0107873
+    , 0.347604
+    , 0.0217787
+    , 0.0109905
+    , 0.0312955
+    , 0.00715399
+    , 0.0939884
+    , 0.303106
+    , 0.0197479
+    , 0.0328352
+    , 0.0135303
+    , 0.000920999
+    , 0.0025714
+    ]
+  , [ 0.00836807
+    , 0.00204339
+    , 0.000222837
+    , 0.000473154
+    , 0.0123984
+    , 0.000482575
+    , 0.000518999
+    , 0.376845
+    , 0.000629617
+    , 0.260833
+    , 0.0315701
+    , 0.000612345
+    , 0.000959592
+    , 0.000949869
+    , 0.000731977
+    , 0.000974638
+    , 0.00499908
+    , 0.293808
+    , 0.000865776
+    , 0.00171323
+    ]
+  , [ 0.222723
+    , 0.164029
+    , 0.000799759
+    , 0.00272808
+    , 0.0228667
+    , 0.0202703
+    , 0.00371839
+    , 0.0455406
+    , 0.00228329
+    , 0.088335
+    , 0.0348095
+    , 0.00612065
+    , 0.00354716
+    , 0.00510519
+    , 0.00648461
+    , 0.085004
+    , 0.101285
+    , 0.169858
+    , 0.00484248
+    , 0.00965
+    ]
+  , [ 0.041214
+    , 0.0204716
+    , 0.00174344
+    , 0.00372634
+    , 0.2239
+    , 0.00691075
+    , 0.0180294
+    , 0.115428
+    , 0.00429003
+    , 0.169356
+    , 0.0414067
+    , 0.00510677
+    , 0.00584164
+    , 0.00575385
+    , 0.00676271
+    , 0.0149106
+    , 0.0239548
+    , 0.120034
+    , 0.0332237
+    , 0.137935
+    ]
+  , [ 0.048055
+    , 0.00378018
+    , 0.208461
+    , 0.185518
+    , 0.0196001
+    , 0.0191402
+    , 0.0872162
+    , 0.00946854
+    , 0.0375741
+    , 0.0277341
+    , 0.00883084
+    , 0.0940629
+    , 0.00812678
+    , 0.0747677
+    , 0.0308438
+    , 0.0439681
+    , 0.0324589
+    , 0.0181769
+    , 0.00346657
+    , 0.03875
+    ]
+  , [ 0.00628487
+    , 0.00730276
+    , 0.000532415
+    , 0.000974149
+    , 0.397455
+    , 0.00195782
+    , 0.0102225
+    , 0.0180592
+    , 0.00162059
+    , 0.117906
+    , 0.0234722
+    , 0.00303425
+    , 0.00201656
+    , 0.00344091
+    , 0.00262469
+    , 0.00569033
+    , 0.00370918
+    , 0.0152754
+    , 0.0598639
+    , 0.318557
+    ]
+  , [ 0.181501
+    , 0.420563
+    , 0.00251455
+    , 0.000708814
+    , 0.00689764
+    , 0.0461854
+    , 0.00143746
+    , 0.00417455
+    , 0.000647425
+    , 0.00983105
+    , 0.00416114
+    , 0.0148485
+    , 0.00387672
+    , 0.0014097
+    , 0.00268454
+    , 0.186454
+    , 0.068719
+    , 0.0345742
+    , 0.00270835
+    , 0.0061033
+    ]
+  , [ 0.0600741
+    , 0.00707198
+    , 0.0170572
+    , 0.0127487
+    , 0.114091
+    , 0.0343564
+    , 0.0305859
+    , 0.0204571
+    , 0.0212367
+    , 0.0994551
+    , 0.0318166
+    , 0.0134869
+    , 0.0297628
+    , 0.014247
+    , 0.0367643
+    , 0.0505793
+    , 0.0339368
+    , 0.0217422
+    , 0.231281
+    , 0.119249
+    ]
+  , [ 0.0708395
+    , 0.0131641
+    , 0.0324483
+    , 0.0508264
+    , 0.059436
+    , 0.0183309
+    , 0.0567273
+    , 0.0650369
+    , 0.0343618
+    , 0.128226
+    , 0.0390363
+    , 0.0416822
+    , 0.0135608
+    , 0.0494875
+    , 0.0474098
+    , 0.0551343
+    , 0.064226
+    , 0.078961
+    , 0.0137118
+    , 0.0673934
+    ]
+  , [ 0.0617689
+    , 0.000719984
+    , 0.343023
+    , 0.379251
+    , 0.000981419
+    , 0.0284659
+    , 0.00795921
+    , 0.00169996
+    , 0.0216077
+    , 0.00399453
+    , 0.00197343
+    , 0.0303082
+    , 0.0174791
+    , 0.0307856
+    , 0.00763329
+    , 0.0337832
+    , 0.0203427
+    , 0.00589923
+    , 0.000613027
+    , 0.00171028
+    ]
+  , [ 0.042156
+    , 0.00444503
+    , 0.0164385
+    , 0.0531949
+    , 0.00867283
+    , 0.0134711
+    , 0.0177765
+    , 0.0267728
+    , 0.132374
+    , 0.196724
+    , 0.118283
+    , 0.0286981
+    , 0.00518379
+    , 0.139369
+    , 0.104207
+    , 0.0255853
+    , 0.0333292
+    , 0.0217067
+    , 0.00458523
+    , 0.00702815
+    ]
+  , [ 0.281481
+    , 0.0258338
+    , 0.00643857
+    , 0.0115046
+    , 0.00504817
+    , 0.0270055
+    , 0.00546297
+    , 0.0188216
+    , 0.00987128
+    , 0.0190993
+    , 0.015872
+    , 0.0172868
+    , 0.012951
+    , 0.0133102
+    , 0.0100367
+    , 0.188681
+    , 0.24271
+    , 0.0837524
+    , 0.00122746
+    , 0.00360529
+    ]
+  , [ 0.276919
+    , 0.0318293
+    , 0.00116725
+    , 0.00247525
+    , 0.00708439
+    , 0.0199647
+    , 0.000517086
+    , 0.0983109
+    , 0.00162322
+    , 0.0489264
+    , 0.0173415
+    , 0.00213153
+    , 0.00701797
+    , 0.00182163
+    , 0.0017227
+    , 0.0336349
+    , 0.0814141
+    , 0.362092
+    , 0.000711814
+    , 0.00329423
+    ]
+  , [ 0.15778
+    , 0.00533181
+    , 0.064829
+    , 0.0913587
+    , 0.00250478
+    , 0.090621
+    , 0.053381
+    , 0.00291716
+    , 0.0782149
+    , 0.0156226
+    , 0.0045759
+    , 0.0570403
+    , 0.00670778
+    , 0.106537
+    , 0.111214
+    , 0.092931
+    , 0.0393123
+    , 0.00850409
+    , 0.00285758
+    , 0.00775903
+    ]
+  , [ 0.0593735
+    , 0.00153322
+    , 0.218948
+    , 0.181942
+    , 0.00108383
+    , 0.0813707
+    , 0.0220478
+    , 0.00209936
+    , 0.0750172
+    , 0.00561913
+    , 0.00218717
+    , 0.115118
+    , 0.0109737
+    , 0.0688752
+    , 0.0354741
+    , 0.0726449
+    , 0.0380238
+    , 0.00426697
+    , 0.000734646
+    , 0.00266649
+    ]
+  , [ 0.0978066
+    , 0.00641384
+    , 0.0120781
+    , 0.0291283
+    , 0.0198964
+    , 0.0128913
+    , 0.0128037
+    , 0.0723904
+    , 0.0245631
+    , 0.127944
+    , 0.0303267
+    , 0.0101844
+    , 0.272352
+    , 0.0307876
+    , 0.0265576
+    , 0.0350549
+    , 0.0484557
+    , 0.115203
+    , 0.00468425
+    , 0.0104774
+    ]
+  , [ 0.0124023
+    , 0.00418857
+    , 0.000603732
+    , 0.0012524
+    , 0.0610615
+    , 0.00113068
+    , 0.00135421
+    , 0.234417
+    , 0.00167182
+    , 0.455056
+    , 0.0667308
+    , 0.00092391
+    , 0.00370762
+    , 0.00329574
+    , 0.00306804
+    , 0.00194209
+    , 0.00676129
+    , 0.129048
+    , 0.00389372
+    , 0.00749118
+    ]
+  , [ 0.0794231
+    , 0.00199195
+    , 0.0587236
+    , 0.12469
+    , 0.001287
+    , 0.0325432
+    , 0.0238605
+    , 0.00362772
+    , 0.21476
+    , 0.0097988
+    , 0.00418462
+    , 0.0662793
+    , 0.014241
+    , 0.114388
+    , 0.129474
+    , 0.0615807
+    , 0.0477334
+    , 0.00781872
+    , 0.000652537
+    , 0.00294202
+    ]
+  , [ 0.0248149
+    , 0.00278397
+    , 0.427883
+    , 0.143239
+    , 0.00146804
+    , 0.0643968
+    , 0.0185737
+    , 0.00225069
+    , 0.0179274
+    , 0.00345586
+    , 0.00157145
+    , 0.188892
+    , 0.0073768
+    , 0.0210778
+    , 0.00835529
+    , 0.0377003
+    , 0.0187768
+    , 0.00460727
+    , 0.000589186
+    , 0.00426027
+    ]
+  , [ 0.00170034
+    , 0.00290594
+    , 0.00107115
+    , 0.00117317
+    , 0.0513377
+    , 0.00355796
+    , 0.00276305
+    , 0.00122912
+    , 0.00042738
+    , 0.0127421
+    , 0.00256713
+    , 0.00042229
+    , 0.00135367
+    , 0.00164242
+    , 0.00606743
+    , 0.00118717
+    , 0.00140331
+    , 0.00331373
+    , 0.864044
+    , 0.0390913
+    ]
+  , [ 0.0468361
+    , 0.00599541
+    , 0.0185616
+    , 0.0705436
+    , 0.00801772
+    , 0.00454353
+    , 0.0152063
+    , 0.155061
+    , 0.0866248
+    , 0.0824253
+    , 0.0245854
+    , 0.0205604
+    , 0.00814856
+    , 0.0557031
+    , 0.0639797
+    , 0.0237026
+    , 0.0962054
+    , 0.204749
+    , 0.00183687
+    , 0.00671317
+    ]
+  , [ 0.0258765
+    , 0.0142504
+    , 0.0107037
+    , 0.010565
+    , 0.187643
+    , 0.0073065
+    , 0.141108
+    , 0.0114778
+    , 0.0119179
+    , 0.0407992
+    , 0.0098799
+    , 0.0298384
+    , 0.00512288
+    , 0.0158529
+    , 0.0201097
+    , 0.02757
+    , 0.0170765
+    , 0.0187502
+    , 0.0405125
+    , 0.353639
+    ]
+  , [ 0.0296285
+    , 0.00900465
+    , 0.000885102
+    , 0.00330465
+    , 0.0408798
+    , 0.00279695
+    , 0.00507015
+    , 0.25834
+    , 0.00466909
+    , 0.266809
+    , 0.0770825
+    , 0.00349444
+    , 0.00269182
+    , 0.00554811
+    , 0.00464003
+    , 0.00685381
+    , 0.0322266
+    , 0.22719
+    , 0.00355061
+    , 0.0153353
+    ]
+  , [ 0.0555726
+    , 0.00974186
+    , 0.014039
+    , 0.00694432
+    , 0.00344967
+    , 0.0157957
+    , 0.00416313
+    , 0.00698265
+    , 0.0139225
+    , 0.00752712
+    , 0.00587627
+    , 0.0409064
+    , 0.0119733
+    , 0.00687277
+    , 0.00984479
+    , 0.348247
+    , 0.421366
+    , 0.0131119
+    , 0.00100615
+    , 0.00265768
+    ]
+  , [ 0.0682671
+    , 0.0141433
+    , 0.0360279
+    , 0.0497415
+    , 0.0803376
+    , 0.0268697
+    , 0.112767
+    , 0.0132647
+    , 0.0482609
+    , 0.0544494
+    , 0.0170034
+    , 0.0530661
+    , 0.019195
+    , 0.0612274
+    , 0.0615207
+    , 0.067184
+    , 0.0443996
+    , 0.0267714
+    , 0.0199958
+    , 0.125507
+    ]
+  , [ 0.0792619
+    , 0.00495033
+    , 0.0436646
+    , 0.0829639
+    , 0.00491311
+    , 0.0183429
+    , 0.0233169
+    , 0.0249427
+    , 0.0932578
+    , 0.0221483
+    , 0.0120893
+    , 0.0635289
+    , 0.012636
+    , 0.0666365
+    , 0.0638377
+    , 0.133485
+    , 0.191675
+    , 0.0503102
+    , 0.00180401
+    , 0.00623531
+    ]
+  , [ 0.0731759
+    , 0.0123459
+    , 0.0110007
+    , 0.0349943
+    , 0.00931488
+    , 0.0224509
+    , 0.0386903
+    , 0.0246226
+    , 0.178334
+    , 0.0508307
+    , 0.0185741
+    , 0.0324201
+    , 0.0148723
+    , 0.0858952
+    , 0.210534
+    , 0.0603181
+    , 0.0649575
+    , 0.038504
+    , 0.00510464
+    , 0.0130597
+    ]
+  , [ 0.0878403
+    , 0.0171147
+    , 0.00328039
+    , 0.0101466
+    , 0.0191954
+    , 0.00870909
+    , 0.00549022
+    , 0.198776
+    , 0.00820969
+    , 0.175646
+    , 0.0417233
+    , 0.00608012
+    , 0.0111284
+    , 0.0109832
+    , 0.0110332
+    , 0.0209863
+    , 0.0697719
+    , 0.28252
+    , 0.0031744
+    , 0.00819055
+    ]
+  , [ 0.0990216
+    , 0.0108996
+    , 0.0118798
+    , 0.0279
+    , 0.0214442
+    , 0.024025
+    , 0.0123445
+    , 0.0776565
+    , 0.0322818
+    , 0.235451
+    , 0.120767
+    , 0.021115
+    , 0.00756555
+    , 0.0557711
+    , 0.0349352
+    , 0.052417
+    , 0.0649785
+    , 0.0771067
+    , 0.00470758
+    , 0.00773287
+    ]
+  , [ 0.0601641
+    , 0.0315067
+    , 0.0337189
+    , 0.00598395
+    , 0.00695259
+    , 0.0543081
+    , 0.0531524
+    , 0.00706508
+    , 0.0139598
+    , 0.00706981
+    , 0.00882987
+    , 0.278352
+    , 0.00758343
+    , 0.0210646
+    , 0.0161995
+    , 0.28298
+    , 0.0860317
+    , 0.0100954
+    , 0.00149666
+    , 0.0134849
+    ]
+  , [ 0.00497817
+    , 0.00529787
+    , 0.000531537
+    , 0.000763055
+    , 0.335112
+    , 0.00150513
+    , 0.00415752
+    , 0.0443829
+    , 0.00116151
+    , 0.441742
+    , 0.0602807
+    , 0.000701221
+    , 0.00278477
+    , 0.00240899
+    , 0.00184123
+    , 0.00257958
+    , 0.00302885
+    , 0.0237677
+    , 0.0171303
+    , 0.0458456
+    ]
+  , [ 0.0251997
+    , 0.00970995
+    , 0.00410123
+    , 0.0262572
+    , 0.0429092
+    , 0.00380673
+    , 0.0431939
+    , 0.0974043
+    , 0.0824313
+    , 0.24472
+    , 0.0539323
+    , 0.0142032
+    , 0.00526585
+    , 0.0620071
+    , 0.111447
+    , 0.00960931
+    , 0.0251183
+    , 0.0783303
+    , 0.0146572
+    , 0.0456965
+    ]
+  , [ 0.0230362
+    , 0.00485801
+    , 0.000626444
+    , 0.00157626
+    , 0.0072127
+    , 0.00115653
+    , 0.000889924
+    , 0.39529
+    , 0.00146635
+    , 0.0576537
+    , 0.0140987
+    , 0.00135344
+    , 0.00201779
+    , 0.000987005
+    , 0.00147487
+    , 0.00287702
+    , 0.0205581
+    , 0.460366
+    , 0.000547769
+    , 0.00195391
+    ]
+  , [ 0.140878
+    , 0.00322137
+    , 0.0285077
+    , 0.0423839
+    , 0.00412311
+    , 0.0299558
+    , 0.0131321
+    , 0.00669145
+    , 0.0383782
+    , 0.019512
+    , 0.00362769
+    , 0.0171298
+    , 0.438347
+    , 0.0320632
+    , 0.0297808
+    , 0.08514
+    , 0.0422766
+    , 0.0198195
+    , 0.00132369
+    , 0.00370876
+    ]
+  , [ 0.444249
+    , 0.0235405
+    , 0.0057193
+    , 0.00648899
+    , 0.00244132
+    , 0.0822688
+    , 0.00255057
+    , 0.00336151
+    , 0.00380971
+    , 0.00409901
+    , 0.00286831
+    , 0.0102305
+    , 0.0162891
+    , 0.00559976
+    , 0.00502166
+    , 0.299997
+    , 0.0559665
+    , 0.0226608
+    , 0.000773543
+    , 0.00206398
+    ]
+  , [ 0.0898718
+    , 0.00441315
+    , 0.0129167
+    , 0.0058957
+    , 0.000807357
+    , 0.808756
+    , 0.00165179
+    , 0.000433928
+    , 0.0033939
+    , 0.00155645
+    , 0.000425342
+    , 0.0130068
+    , 0.00341281
+    , 0.00238065
+    , 0.00709583
+    , 0.0362877
+    , 0.00328875
+    , 0.00202896
+    , 0.00152239
+    , 0.000853745
+    ]
+  , [ 0.055084
+    , 0.00358249
+    , 0.12738
+    , 0.0655885
+    , 0.0040375
+    , 0.0637608
+    , 0.0404883
+    , 0.00755742
+    , 0.0867683
+    , 0.0136305
+    , 0.00816842
+    , 0.187783
+    , 0.0110682
+    , 0.0527969
+    , 0.0472254
+    , 0.126338
+    , 0.0752544
+    , 0.0102728
+    , 0.00135637
+    , 0.011859
+    ]
+  , [ 0.0117681
+    , 0.00703883
+    , 0.0144712
+    , 0.0110901
+    , 0.0338266
+    , 0.00496266
+    , 0.433719
+    , 0.0061337
+    , 0.0137929
+    , 0.0298795
+    , 0.00762376
+    , 0.0844145
+    , 0.00813461
+    , 0.103834
+    , 0.0442559
+    , 0.0140571
+    , 0.0108277
+    , 0.00837578
+    , 0.00806831
+    , 0.143725
+    ]
+  , [ 0.0159286
+    , 0.00805199
+    , 0.00109669
+    , 0.00213242
+    , 0.0743651
+    , 0.00250864
+    , 0.00491921
+    , 0.0501544
+    , 0.00355994
+    , 0.530763
+    , 0.216009
+    , 0.00326926
+    , 0.00452474
+    , 0.0134552
+    , 0.00480987
+    , 0.00669222
+    , 0.0119092
+    , 0.0281012
+    , 0.00709281
+    , 0.0106565
+    ]
+  , [ 0.0195973
+    , 0.0034539
+    , 0.309985
+    , 0.0250778
+    , 0.00197065
+    , 0.0627529
+    , 0.0295961
+    , 0.00326504
+    , 0.0240964
+    , 0.00282469
+    , 0.000842506
+    , 0.32891
+    , 0.00490628
+    , 0.0116197
+    , 0.0105143
+    , 0.106498
+    , 0.0438054
+    , 0.0040302
+    , 0.000633396
+    , 0.0056198
+    ]
+  , [ 0.0833804
+    , 0.00819811
+    , 0.0686821
+    , 0.0227415
+    , 0.00241326
+    , 0.0982292
+    , 0.00739549
+    , 0.00174712
+    , 0.0129342
+    , 0.00396531
+    , 0.0019558
+    , 0.0969824
+    , 0.0355924
+    , 0.0121521
+    , 0.0125871
+    , 0.311561
+    , 0.211337
+    , 0.00471386
+    , 0.0016329
+    , 0.00179911
+    ]
+  , [ 0.0181409
+    , 0.00851436
+    , 0.00333335
+    , 0.00965319
+    , 0.00354269
+    , 0.0224553
+    , 0.0375239
+    , 0.00350905
+    , 0.320807
+    , 0.0149147
+    , 0.00460989
+    , 0.0233205
+    , 0.00871975
+    , 0.0526694
+    , 0.412966
+    , 0.0262309
+    , 0.0131791
+    , 0.00447465
+    , 0.0034767
+    , 0.00795882
+    ]
+  , [ 0.249423
+    , 0.0122863
+    , 0.0169234
+    , 0.0370491
+    , 0.00773609
+    , 0.0347468
+    , 0.00870696
+    , 0.0595718
+    , 0.0177065
+    , 0.0451065
+    , 0.0204556
+    , 0.016412
+    , 0.0686404
+    , 0.0228502
+    , 0.0185482
+    , 0.0889296
+    , 0.0986017
+    , 0.167252
+    , 0.00286039
+    , 0.00619385
+    ]
+  , [ 0.141974
+    , 0.00688567
+    , 0.0537452
+    , 0.040754
+    , 0.00402861
+    , 0.398811
+    , 0.0152896
+    , 0.00166276
+    , 0.0314274
+    , 0.00923483
+    , 0.00554255
+    , 0.0576297
+    , 0.0180329
+    , 0.028624
+    , 0.0373946
+    , 0.112373
+    , 0.0242478
+    , 0.00484629
+    , 0.00259091
+    , 0.00490542
+    ]
+  , [ 0.0178903
+    , 0.0290304
+    , 0.00310543
+    , 0.00405034
+    , 0.0238913
+    , 0.010048
+    , 0.12527
+    , 0.0016708
+    , 0.023334
+    , 0.0722357
+    , 0.0116142
+    , 0.0155854
+    , 0.000993842
+    , 0.105182
+    , 0.195884
+    , 0.0181676
+    , 0.018626
+    , 0.0113865
+    , 0.226055
+    , 0.0859787
+    ]
+  , [ 0.145476
+    , 0.00141863
+    , 0.129425
+    , 0.247135
+    , 0.00175521
+    , 0.0319651
+    , 0.0130426
+    , 0.00585254
+    , 0.0818154
+    , 0.0123593
+    , 0.00441789
+    , 0.040042
+    , 0.0151136
+    , 0.0906469
+    , 0.0420979
+    , 0.0656688
+    , 0.0511289
+    , 0.0169401
+    , 0.000773144
+    , 0.00292584
+    ]
+  , [ 0.0169799
+    , 0.00220872
+    , 0.104366
+    , 0.037638
+    , 0.000678059
+    , 0.540447
+    , 0.0181137
+    , 0.000745968
+    , 0.0508618
+    , 0.0021147
+    , 0.000947377
+    , 0.131805
+    , 0.00387544
+    , 0.026935
+    , 0.0242347
+    , 0.029703
+    , 0.00458362
+    , 0.00158917
+    , 0.000603189
+    , 0.00157041
+    ]
+  , [ 0.0402646
+    , 0.00393887
+    , 0.0293968
+    , 0.160352
+    , 0.00411534
+    , 0.012926
+    , 0.0617968
+    , 0.00984913
+    , 0.14488
+    , 0.0354919
+    , 0.0124819
+    , 0.0323829
+    , 0.00433742
+    , 0.249701
+    , 0.115202
+    , 0.0243247
+    , 0.0305645
+    , 0.0156027
+    , 0.00266766
+    , 0.00972278
+    ]
+  , [ 0.225691
+    , 0.00433901
+    , 0.0637125
+    , 0.115483
+    , 0.00274401
+    , 0.0867335
+    , 0.0131067
+    , 0.00850862
+    , 0.0660469
+    , 0.0193314
+    , 0.00648772
+    , 0.0244309
+    , 0.0611149
+    , 0.0578159
+    , 0.0523417
+    , 0.107088
+    , 0.0507677
+    , 0.0299883
+    , 0.00136959
+    , 0.00289829
+    ]
+  , [ 0.00331642
+    , 0.00518907
+    , 0.000826647
+    , 0.000513413
+    , 0.380176
+    , 0.00104328
+    , 0.0278451
+    , 0.00418953
+    , 0.000714992
+    , 0.0111212
+    , 0.00236218
+    , 0.00308302
+    , 0.000836508
+    , 0.00110249
+    , 0.00153108
+    , 0.00358767
+    , 0.00236089
+    , 0.00607663
+    , 0.0333347
+    , 0.510789
+    ]
+  , [ 0.199501
+    , 0.058459
+    , 0.00949551
+    , 0.0125535
+    , 0.0634434
+    , 0.0939787
+    , 0.0341857
+    , 0.014021
+    , 0.0118723
+    , 0.0449388
+    , 0.0246991
+    , 0.0392255
+    , 0.0145385
+    , 0.0254265
+    , 0.0236079
+    , 0.166392
+    , 0.0533159
+    , 0.0367303
+    , 0.0129803
+    , 0.0606346
+    ]
+  , [ 0.0319449
+    , 0.00660403
+    , 0.0378075
+    , 0.0279488
+    , 0.0108916
+    , 0.0365541
+    , 0.208864
+    , 0.00475423
+    , 0.0868665
+    , 0.0156546
+    , 0.00432533
+    , 0.208471
+    , 0.00608996
+    , 0.0766373
+    , 0.101167
+    , 0.0577657
+    , 0.0302051
+    , 0.00605852
+    , 0.00260019
+    , 0.0387897
+    ]
+  , [ 0.07768
+    , 0.0140093
+    , 0.00806517
+    , 0.0112622
+    , 0.0173585
+    , 0.0136868
+    , 0.013373
+    , 0.123964
+    , 0.0129145
+    , 0.0724671
+    , 0.0420745
+    , 0.0403217
+    , 0.0117084
+    , 0.0179996
+    , 0.0142519
+    , 0.0922724
+    , 0.23169
+    , 0.167914
+    , 0.00281536
+    , 0.0141727
+    ]
+  , [ 0.118366
+    , 0.00356248
+    , 0.0495595
+    , 0.153759
+    , 0.00686657
+    , 0.0194993
+    , 0.0229373
+    , 0.0302661
+    , 0.0982304
+    , 0.0571251
+    , 0.0171727
+    , 0.0259525
+    , 0.0175153
+    , 0.120492
+    , 0.0805193
+    , 0.0486588
+    , 0.0635796
+    , 0.0553336
+    , 0.00230083
+    , 0.00830274
+    ]
+  , [ 0.052856
+    , 0.000862588
+    , 0.209276
+    , 0.402419
+    , 0.00126507
+    , 0.0155838
+    , 0.0124149
+    , 0.00548648
+    , 0.0497017
+    , 0.00902565
+    , 0.00423571
+    , 0.0264744
+    , 0.00631856
+    , 0.121241
+    , 0.0193569
+    , 0.0197263
+    , 0.0235464
+    , 0.0159764
+    , 0.000838161
+    , 0.00339487
+    ]
+  , [ 0.0344366
+    , 0.0020986
+    , 0.113901
+    , 0.054178
+    , 0.00315576
+    , 0.336164
+    , 0.0461777
+    , 0.000346342
+    , 0.0667553
+    , 0.00483557
+    , 0.00197045
+    , 0.163672
+    , 0.00403698
+    , 0.0605414
+    , 0.0426222
+    , 0.0481173
+    , 0.00891481
+    , 0.00201106
+    , 0.00065101
+    , 0.00541456
+    ]
+  , [ 0.115309
+    , 0.00149624
+    , 0.175552
+    , 0.174941
+    , 0.00157002
+    , 0.0394181
+    , 0.0132402
+    , 0.0056913
+    , 0.0433118
+    , 0.010141
+    , 0.00303321
+    , 0.0458477
+    , 0.16658
+    , 0.0366731
+    , 0.0151279
+    , 0.0871536
+    , 0.0468261
+    , 0.0141932
+    , 0.00075157
+    , 0.00314327
+    ]
+  , [ 0.386515
+    , 0.0218928
+    , 0.00223668
+    , 0.00313878
+    , 0.00392814
+    , 0.369435
+    , 0.00146729
+    , 0.00853761
+    , 0.00188405
+    , 0.0127257
+    , 0.00805817
+    , 0.00304205
+    , 0.0158688
+    , 0.00214647
+    , 0.00375793
+    , 0.0808877
+    , 0.0305196
+    , 0.0410635
+    , 0.000992288
+    , 0.00190203
+    ]
+  , [ 0.0146571
+    , 0.00243179
+    , 0.000521057
+    , 0.00148744
+    , 0.00916375
+    , 0.00209533
+    , 0.00101819
+    , 0.19139
+    , 0.00228984
+    , 0.44328
+    , 0.221743
+    , 0.00129983
+    , 0.000768515
+    , 0.00493628
+    , 0.00288413
+    , 0.00272515
+    , 0.0170997
+    , 0.0778557
+    , 0.000877938
+    , 0.0014756
+    ]
+  ]
+
+-- | Weights of C60 model.
+c60Weights :: [Double]
+c60Weights =
+  [ 0.0169699
+  , 0.0211683
+  , 0.0276589
+  , 0.0065676
+  , 0.0141221
+  , 0.00687748
+  , 0.014691
+  , 0.00672258
+  , 0.00183967
+  , 0.0102547
+  , 0.0230896
+  , 0.0057941
+  , 0.0125395
+  , 0.0204526
+  , 0.00706296
+  , 0.0117983
+  , 0.00683347
+  , 0.0433776
+  , 0.0318279
+  , 0.0222546
+  , 0.0102265
+  , 0.0150546
+  , 0.013416
+  , 0.0148552
+  , 0.0239112
+  , 0.0128776
+  , 0.0222319
+  , 0.0247445
+  , 0.0214275
+  , 0.0115002
+  , 0.00760174
+  , 0.0130259
+  , 0.0093702
+  , 0.0467194
+  , 0.044194
+  , 0.0322263
+  , 0.0403
+  , 0.0150234
+  , 0.010459
+  , 0.0214742
+  , 0.0154958
+  , 0.010179
+  , 0.022798
+  , 0.0123205
+  , 0.00667776
+  , 0.000415008
+  , 0.0344385
+  , 0.0113663
+  , 0.0127143
+  , 0.0124324
+  , 0.0262124
+  , 0.0064995
+  , 0.0103203
+  , 0.0142464
+  , 0.02156
+  , 0.0199151
+  , 0.00389642
+  , 0.0113449
+  , 0.0128596
+  , 0.0117657
+  ]
diff --git a/src/ELynx/Data/MarkovProcess/GammaRateHeterogeneity.hs b/src/ELynx/Data/MarkovProcess/GammaRateHeterogeneity.hs
new file mode 100644
--- /dev/null
+++ b/src/ELynx/Data/MarkovProcess/GammaRateHeterogeneity.hs
@@ -0,0 +1,131 @@
+{- |
+Module      :  ELynx.Data.MarkovProcess.GammaRateHeterogeneity
+Description :  Discrete gamma rate heterogeneity
+Copyright   :  (c) Dominik Schrempf 2020
+License     :  GPL-3.0-or-later
+
+Maintainer  :  dominik.schrempf@gmail.com
+Stability   :  unstable
+Portability :  portable
+
+Creation date: Thu Feb 28 14:09:11 2019.
+
+At the moment, a mixture model is used to emulate gamma rate heterogeneity. This
+does not come with huge run time increases when simulating data. For inference
+however, it would make a lot of sense to reuse the Eigendecomposition for all
+rate heterogeneity components though.
+
+-}
+
+module ELynx.Data.MarkovProcess.GammaRateHeterogeneity
+  ( summarizeGammaRateHeterogeneity
+  , expand
+  )
+where
+
+import           Prelude                 hiding ( repeat )
+
+import qualified Data.ByteString.Lazy.Char8    as L
+import qualified Data.List.NonEmpty            as N
+import           Data.List.NonEmpty             ( NonEmpty )
+import           Numeric.Integration.TanhSinh
+import           Statistics.Distribution
+import           Statistics.Distribution.Gamma
+
+import qualified ELynx.Data.MarkovProcess.MixtureModel
+                                               as M
+import qualified ELynx.Data.MarkovProcess.PhyloModel
+                                               as P
+import qualified ELynx.Data.MarkovProcess.SubstitutionModel
+                                               as S
+
+-- | Short summary of gamma rate heterogeneity parameters.
+summarizeGammaRateHeterogeneity :: Int -> Double -> [L.ByteString]
+summarizeGammaRateHeterogeneity n alpha = map
+  L.pack
+  [ "Discrete gamma rate heterogeneity."
+  , "Number of categories: " ++ show n
+  , "Shape parameter of gamma distribution: " ++ show alpha
+  , "Rates: " ++ show (getMeans n alpha)
+  ]
+
+-- | For a given number of rate categories, a gamma shape parameter alpha and a
+-- substitution model, compute the scaled substitution models corresponding to
+-- the gamma rates.
+expand :: Int -> Double -> P.PhyloModel -> P.PhyloModel
+expand n alpha (P.SubstitutionModel sm) =
+  P.MixtureModel $ expandSubstitutionModel n alpha sm
+expand n alpha (P.MixtureModel mm) =
+  P.MixtureModel $ expandMixtureModel n alpha mm
+
+getName :: Int -> Double -> String
+getName n alpha =
+  " with discrete gamma rate heterogeneity; "
+    ++ show n
+    ++ " categories; "
+    ++ "shape parameter "
+    ++ show alpha
+
+splitSubstitutionModel
+  :: Int -> Double -> S.SubstitutionModel -> NonEmpty S.SubstitutionModel
+splitSubstitutionModel n alpha sm = renamedSMs
+ where
+  means      = getMeans n alpha
+  scaledSMs  = N.map (`S.scale` sm) means
+  names = N.fromList $ map (("; gamma rate category " ++) . show) [1 :: Int ..]
+  renamedSMs = N.zipWith S.appendName names scaledSMs
+
+expandSubstitutionModel
+  :: Int -> Double -> S.SubstitutionModel -> M.MixtureModel
+expandSubstitutionModel n alpha sm = M.fromSubstitutionModels name ws sms
+ where
+  name = S.name sm <> getName n alpha
+  ws   = N.repeat 1.0
+  sms  = splitSubstitutionModel n alpha sm
+
+expandMixtureModel :: Int -> Double -> M.MixtureModel -> M.MixtureModel
+expandMixtureModel n alpha mm = M.concatenate name renamedMMs
+ where
+  name       = M.name mm <> getName n alpha
+  means      = getMeans n alpha
+  scaledMMs  = N.map (`M.scale` mm) means
+  names = N.fromList $ map (("; gamma rate category " ++) . show) [1 :: Int ..]
+  renamedMMs = N.zipWith M.appendNameComponents names scaledMMs
+
+-- For a given number of rate categories 'n' and a shape parameter 'alpha' (the
+-- rate or scale is set such that the mean is 1.0), return a list of rates that
+-- represent the respective categories. Use the mean rate for each category.
+getMeans :: Int -> Double -> NonEmpty Double
+getMeans n alpha = N.fromList $ means <> pure lastMean
+ where
+  gamma = gammaDistr alpha (1.0 / alpha)
+  quantiles =
+    [ quantile gamma (fromIntegral i / fromIntegral n) | i <- [0 .. n] ]
+  -- Calculate the mean rate. Multiplication with the number of rate
+  -- categories 'n' is necessary because in each n-quantile the
+  -- probability mass is 1/n.
+  meanFunc x = fromIntegral n * x * density gamma x
+  -- Only calculate the first (n-1) categories with normal integration.
+  means =
+    [ integralAToB meanFunc (quantiles !! i) (quantiles !! (i + 1))
+    | i <- [0 .. n - 2]
+    ]
+  -- The last category has to be calculated with an improper integration.
+  lastMean = integralAToInf meanFunc (quantiles !! (n - 1))
+
+-- The error of integration.
+eps :: Double
+eps = 1e-6
+
+-- The integration method to use
+method :: (Double -> Double) -> Double -> Double -> [Result]
+method = parSimpson
+
+-- Helper function for a normal integral from 'a' to 'b'.
+integralAToB :: (Double -> Double) -> Double -> Double -> Double
+integralAToB f a b = result . absolute eps $ method f a b
+
+-- Helper function for an improper integral from 'a' to infinity.
+integralAToInf :: (Double -> Double) -> Double -> Double
+integralAToInf f a =
+  (result . absolute eps $ nonNegative method f) - integralAToB f 0 a
diff --git a/src/ELynx/Data/MarkovProcess/MixtureModel.hs b/src/ELynx/Data/MarkovProcess/MixtureModel.hs
new file mode 100644
--- /dev/null
+++ b/src/ELynx/Data/MarkovProcess/MixtureModel.hs
@@ -0,0 +1,158 @@
+{- |
+Module      :  ELynx.Data.MarkovProcess.MixtureModel
+Description :  Mixture models are a set of substitution models with weights
+Copyright   :  (c) Dominik Schrempf 2020
+License     :  GPL-3.0-or-later
+
+Maintainer  :  dominik.schrempf@gmail.com
+Stability   :  unstable
+Portability :  portable
+
+Creation date: Tue Jan 29 19:17:40 2019.
+
+To be imported qualified.
+
+-}
+
+module ELynx.Data.MarkovProcess.MixtureModel
+  ( -- * Types
+    Weight
+  , Component
+  , MixtureModel(name)
+  , -- * Getters
+    getAlphabet
+  , getWeights
+  , getSubstitutionModels
+    -- * Building mixture models
+  , fromSubstitutionModels
+    -- * Transformations
+  , concatenate
+  , scale
+  , normalize
+  , appendNameComponents
+  -- * Output
+  , summarizeComponent
+  , summarize
+  )
+where
+
+import           Prelude                 hiding ( map
+                                                , head
+                                                , zipWith
+                                                , length
+                                                )
+
+import qualified Data.ByteString.Builder       as L
+import qualified Data.ByteString.Lazy.Char8    as L
+import           Data.List.NonEmpty      hiding ( zip )
+import           Data.Semigroup
+
+import           ELynx.Data.Alphabet.Alphabet
+
+import           ELynx.Tools
+
+import qualified ELynx.Data.MarkovProcess.SubstitutionModel
+                                               as S
+
+-- | Mixture model component weight.
+type Weight = Double
+
+-- | A mixture model component has a weight and a substitution model.
+data Component = Component
+  { weight     :: Weight
+  , substModel :: S.SubstitutionModel
+  }
+  deriving (Show, Read)
+
+-- | A mixture model with its components.
+data MixtureModel = MixtureModel
+  { name       :: S.Name        -- ^ Name
+  , alphabet   :: Alphabet
+  , components :: NonEmpty Component
+  }
+  deriving (Show, Read)
+
+-- | Get alphabet used with mixture model. Throws error if components use
+-- different 'Alphabet's.
+getAlphabet :: MixtureModel -> Alphabet
+getAlphabet = alphabet
+
+-- | Get weights.
+getWeights :: MixtureModel -> NonEmpty Weight
+getWeights = map weight . components
+
+-- | Get substitution models.
+getSubstitutionModels :: MixtureModel -> NonEmpty S.SubstitutionModel
+getSubstitutionModels = map substModel . components
+
+-- | Create a mixture model from a list of substitution models.
+fromSubstitutionModels
+  :: S.Name -> NonEmpty Weight -> NonEmpty S.SubstitutionModel -> MixtureModel
+fromSubstitutionModels n ws sms = if allEqual $ toList alphs
+  then MixtureModel n (head alphs) comps
+  else error
+    "fromSubstitutionModels: alphabets of substitution models are not equal."
+ where
+  comps = zipWith Component ws sms
+  alphs = map S.alphabet sms
+
+-- | Concatenate mixture models.
+concatenate :: S.Name -> NonEmpty MixtureModel -> MixtureModel
+concatenate n mms = fromSubstitutionModels n ws sms
+ where
+  comps = sconcat $ map components mms
+  ws    = map weight comps
+  sms   = map substModel comps
+
+scaleComponent :: Double -> Component -> Component
+scaleComponent s c = c { substModel = s' } where s' = S.scale s $ substModel c
+
+-- | Scale all substitution models of the mixture model.
+scale :: Double -> MixtureModel -> MixtureModel
+scale s m = m { components = cs' }
+ where
+  cs  = components m
+  cs' = map (scaleComponent s) cs
+
+-- | Globally normalize a mixture model so that on average one event happens per
+-- unit time.
+normalize :: MixtureModel -> MixtureModel
+normalize mm = scale (1 / c) mm
+ where
+  c       = sum $ zipWith (*) weights scales
+  weights = getWeights mm
+  scales  = map S.totalRate $ getSubstitutionModels mm
+
+appendNameComponent :: S.Name -> Component -> Component
+appendNameComponent n c = c { substModel = s' }
+  where s' = S.appendName n $ substModel c
+
+-- | Append byte string to all substitution models of mixture model.
+appendNameComponents :: S.Name -> MixtureModel -> MixtureModel
+appendNameComponents n m = m { components = cs' }
+ where
+  cs  = components m
+  cs' = map (appendNameComponent n) cs
+
+-- | Summarize a mixture model component; lines to be printed to screen or log.
+summarizeComponent :: Component -> [L.ByteString]
+summarizeComponent c =
+  L.pack "Weight: "
+    <> (L.toLazyByteString . L.doubleDec $ weight c)
+    :  S.summarize (substModel c)
+
+-- | Summarize a mixture model; lines to be printed to screen or log.
+summarize :: MixtureModel -> [L.ByteString]
+summarize m =
+  [ L.pack $ "Mixture model: " ++ name m ++ "."
+    , L.pack $ "Number of components: " ++ show n ++ "."
+    ]
+    ++ detail
+ where
+  n      = length $ components m
+  detail = if n <= 100
+    then concat
+      [ L.pack ("Component " ++ show i ++ ":") : summarizeComponent c
+      | (i, c) <- zip [1 :: Int ..] (toList $ components m)
+      ]
+    else []
diff --git a/src/ELynx/Data/MarkovProcess/Nucleotide.hs b/src/ELynx/Data/MarkovProcess/Nucleotide.hs
new file mode 100644
--- /dev/null
+++ b/src/ELynx/Data/MarkovProcess/Nucleotide.hs
@@ -0,0 +1,104 @@
+{- |
+Module      :  ELynx.Data.MarkovProcess.Nucleotide
+Description :  Substitution models using nucleotides
+Copyright   :  (c) Dominik Schrempf 2020
+License     :  GPL-3.0-or-later
+
+Maintainer  :  dominik.schrempf@gmail.com
+Stability   :  unstable
+Portability :  portable
+
+Creation date: Thu Jan 24 08:33:26 2019.
+
+XXX: Maybe rename to something like /DNA substitution models/. Nucleotide ~
+Alphabet; DNA ~ Character.
+
+The order of nucleotides is A, C, G, T; see 'ELynx.Data.Character.Nucleotide'.
+
+For the different DNA substitution models, please see
+https://en.wikipedia.org/wiki/Models_of_DNA_evolution
+
+-}
+
+module ELynx.Data.MarkovProcess.Nucleotide
+  ( jc
+  , f81
+  , hky
+  , gtr4
+  )
+where
+
+import           Numeric.LinearAlgebra   hiding ( normalize )
+
+import           ELynx.Data.Alphabet.Alphabet
+
+import           ELynx.Tools
+
+import           ELynx.Data.MarkovProcess.RateMatrix
+import           ELynx.Data.MarkovProcess.SubstitutionModel
+
+-- XXX: Another idea of structuring the code. This would probably be cleaner in
+-- the long run.
+
+-- data PhyloModel = MixtureModel | SubstitutionModel
+
+--
+-- I think it could simply be:
+-- data PhyloModel = [(Weight, SubstitutionModel)]
+--
+
+-- data MixtureModel = [(Weight, SubstitutionModel)]
+
+-- data SubstitutionModel = SMDNA DNASubstitutionModel | SMAA AASubstitutionModel
+
+-- data DNASubstitutionModel = JC | HKY Double StationaryDistribution
+
+-- data AASubstitutionModel = LG | ...
+
+n :: Int
+-- n = length (alphabet :: [Nucleotide])
+-- Hard code this here. Reduces model dependencies, and number of nucleotides
+-- will not change.
+n = 4
+
+-- | JC model matrix.
+jcExch :: ExchangeabilityMatrix
+jcExch = (n >< n)
+  [ 0.0
+  , 1.0
+  , 1.0
+  , 1.0
+  , 1.0
+  , 0.0
+  , 1.0
+  , 1.0
+  , 1.0
+  , 1.0
+  , 0.0
+  , 1.0
+  , 1.0
+  , 1.0
+  , 1.0
+  , 0.0
+  ]
+
+-- | JC substitution model.
+jc :: SubstitutionModel
+jc = substitutionModel DNA "JC" [] d jcExch where d = uniformVec n
+
+-- | F81 substitution model.
+f81 :: StationaryDistribution -> SubstitutionModel
+f81 d = substitutionModel DNA "F81" [] d jcExch
+
+hkyExch :: Double -> ExchangeabilityMatrix
+hkyExch k = (n >< n)
+  [0.0, 1.0, k, 1.0, 1.0, 0.0, 1.0, k, k, 1.0, 0.0, 1.0, 1.0, k, 1.0, 0.0]
+
+-- | HKY substitution model.
+hky :: Double -> StationaryDistribution -> SubstitutionModel
+hky k d = substitutionModel DNA "HKY" [k] d e where e = hkyExch k
+
+-- | HKY substitution model.
+gtr4 :: [Double] -> StationaryDistribution -> SubstitutionModel
+gtr4 es d = substitutionModel DNA "GTR" es d e
+  where e = exchFromListUpper n es
diff --git a/src/ELynx/Data/MarkovProcess/PhyloModel.hs b/src/ELynx/Data/MarkovProcess/PhyloModel.hs
new file mode 100644
--- /dev/null
+++ b/src/ELynx/Data/MarkovProcess/PhyloModel.hs
@@ -0,0 +1,50 @@
+{- |
+Module      :  ELynx.Data.MarkovProcess.PhyloModel
+Description :  Phylogenetic model
+Copyright   :  (c) Dominik Schrempf 2020
+License     :  GPL-3.0-or-later
+
+Maintainer  :  dominik.schrempf@gmail.com
+Stability   :  unstable
+Portability :  portable
+
+Creation date: Fri Feb  1 12:43:06 2019.
+
+A phylogenetic model is a complete description of the evolutionary process. At
+the moment, it is either a mixture model or a plain substitution model, but more
+complicated models may be added in the future.
+
+To be imported qualified.
+
+-}
+
+module ELynx.Data.MarkovProcess.PhyloModel
+  ( PhyloModel(..)
+  , getAlphabet
+  , summarize
+  )
+where
+
+import qualified Data.ByteString.Lazy.Char8    as L
+
+import           ELynx.Data.Alphabet.Alphabet
+
+import qualified ELynx.Data.MarkovProcess.MixtureModel
+                                               as M
+import qualified ELynx.Data.MarkovProcess.SubstitutionModel
+                                               as S
+
+-- | A phylogenetic model is a mixture model or a substitution model. More
+-- complicated models may be added.
+data PhyloModel = MixtureModel M.MixtureModel | SubstitutionModel S.SubstitutionModel
+  deriving (Show, Read)
+
+-- | Extract code from phylogenetic model.
+getAlphabet :: PhyloModel -> Alphabet
+getAlphabet (MixtureModel      mm) = M.getAlphabet mm
+getAlphabet (SubstitutionModel sm) = S.alphabet sm
+
+-- | Summarize a phylogenetic model; lines to be printed to screen or log.
+summarize :: PhyloModel -> [L.ByteString]
+summarize (MixtureModel      mm) = M.summarize mm
+summarize (SubstitutionModel sm) = S.summarize sm
diff --git a/src/ELynx/Data/MarkovProcess/RateMatrix.hs b/src/ELynx/Data/MarkovProcess/RateMatrix.hs
new file mode 100644
--- /dev/null
+++ b/src/ELynx/Data/MarkovProcess/RateMatrix.hs
@@ -0,0 +1,210 @@
+{-# LANGUAGE FlexibleContexts #-}
+
+{- |
+Description :  Rate matrix helper functions
+Copyright   :  (c) Dominik Schrempf 2017
+License     :  GPLv3
+
+Maintainer  :  dominik.schrempf@gmail.com
+Stability   :  unstable
+Portability :  non-portable (not tested)
+
+Some helper functions that come handy when working with rate matrices of
+continuous-time discrete-state Markov processes.
+
+* Changelog
+
+To be imported qualified.
+
+-}
+
+module ELynx.Data.MarkovProcess.RateMatrix
+  ( RateMatrix
+  , ExchangeabilityMatrix
+  , StationaryDistribution
+  , isValid
+  , normalizeSD
+  , totalRate
+  , totalRateWith
+  , normalize
+  , normalizeWith
+  , setDiagonal
+  , toExchangeabilityMatrix
+  , fromExchangeabilityMatrix
+  , getStationaryDistribution
+  , exchFromListLower
+  , exchFromListUpper
+  )
+where
+
+import           Prelude                 hiding ( (<>) )
+
+import           Numeric.LinearAlgebra   hiding ( normalize )
+import           Numeric.SpecFunctions
+
+import           ELynx.Tools
+
+-- | A rate matrix is just a real matrix.
+type RateMatrix = Matrix R
+
+-- | A matrix of exchangeabilities, we have q = e * pi, where q is a rate
+-- matrix, e is the exchangeability matrix and pi is the diagonal matrix
+-- containing the stationary frequency distribution.
+type ExchangeabilityMatrix = Matrix R
+
+-- | Stationary distribution of a rate matrix.
+type StationaryDistribution = Vector R
+
+-- | True if distribution sums to 1.0.
+isValid :: StationaryDistribution -> Bool
+isValid d = nearlyEqWith eps' (norm_1 d) 1.0
+
+-- | Normalize a stationary distribution so that the elements sum to 1.0.
+normalizeSD :: StationaryDistribution -> StationaryDistribution
+normalizeSD d = d / scalar (norm_1 d)
+
+-- | Get average number of substitutions per unit time.
+totalRateWith :: StationaryDistribution -> RateMatrix -> Double
+totalRateWith d m = norm_1 $ d <# matrixSetDiagToZero m
+
+-- | Get average number of substitutions per unit time.
+totalRate :: RateMatrix -> Double
+totalRate m = totalRateWith (getStationaryDistribution m) m
+
+-- | Normalizes a Markov process generator such that one event happens per unit
+-- time. Calculates stationary distribution from rate matrix.
+normalize :: RateMatrix -> RateMatrix
+normalize m = normalizeWith (getStationaryDistribution m) m
+
+-- | Normalizes a Markov process generator such that one event happens per unit
+-- time. Faster, but stationary distribution has to be given.
+normalizeWith :: StationaryDistribution -> RateMatrix -> RateMatrix
+normalizeWith d m = scale (1.0 / totalRateWith d m) m
+
+-- | Set the diagonal entries of a matrix such that the rows sum to 0.
+setDiagonal :: RateMatrix -> RateMatrix
+setDiagonal m = diagZeroes - diag (fromList rowSums)
+ where
+  diagZeroes = matrixSetDiagToZero m
+  rowSums    = map norm_1 $ toRows diagZeroes
+
+-- | Extract the exchangeability matrix from a rate matrix.
+toExchangeabilityMatrix
+  :: RateMatrix -> StationaryDistribution -> ExchangeabilityMatrix
+toExchangeabilityMatrix m f = m <> diag oneOverF
+  where oneOverF = cmap (1.0 /) f
+
+-- | Convert exchangeability matrix to rate matrix.
+fromExchangeabilityMatrix
+  :: ExchangeabilityMatrix -> StationaryDistribution -> RateMatrix
+fromExchangeabilityMatrix em d = setDiagonal $ em <> diag d
+
+-- | Get stationary distribution from 'RateMatrix'. Involves eigendecomposition.
+-- If the given matrix does not satisfy the required properties of transition
+-- rate matrices and no eigenvector with an eigenvalue nearly equal to 0 is
+-- found, an error is thrown. Is there an easier way to calculate the stationary
+-- distribution or a better way to handle errors (of course I could use the
+-- Maybe monad, but then the error report is just delayed to the calling
+-- function)?
+getStationaryDistribution :: RateMatrix -> StationaryDistribution
+getStationaryDistribution m = if magnitude (eVals ! i) `nearlyEq` 0
+  then normalizeSumVec 1.0 distReal
+  else error
+    "getStationaryDistribution: Could not retrieve stationary distribution."
+ where
+  (eVals, eVecs) = eig (tr m)
+  i              = minIndex eVals
+  distComplex    = toColumns eVecs !! i
+  distReal       = cmap realPart distComplex
+
+-- The next functions tackle the somewhat trivial, but not easily solvable
+-- problem of converting a triangular matrix (excluding the diagonal) given as a
+-- list into a symmetric matrix. The diagonal entries are set to zero.
+
+-- Lower triangular matrix. This is how the exchangeabilities are specified in
+-- PAML. Conversion from matrix indices (i,j) to list index k.
+--
+-- (i,j) k
+--
+-- (0,0) -
+-- (1,0) 0  (1,1) -
+-- (2,0) 1  (2,1) 2  (2,2) -
+-- (3,0) 3  (3,1) 4  (3,2) 5 (3,3) -
+-- (4,0) 6  (4,1) 7  (4,2) 8 (4,3) 9 (4,4) -
+--   .
+--   .
+--   .
+--
+-- k = (i choose 2) + j.
+ijToKLower :: Int -> Int -> Int
+ijToKLower i j
+  | i > j     = round (i `choose` 2) + j
+  | otherwise = error "ijToKLower: not defined for upper triangular matrix."
+
+
+-- Upper triangular matrix. Conversion from matrix indices (i,j) to list index
+-- k. Matrix is square of size n.
+--
+-- (i,j) k
+--
+-- (0,0) -  (0,1) 0  (0,2) 1    (0,3) 2     (0,4) 3     ...
+--          (1,1) -  (1,2) n-1  (1,3) n     (1,4) n+1
+--                   (2,2) -    (2,3) 2n-3  (2,4) 2n-2
+--                              (3,3) -     (3,4) 3n-6
+--                                          (4,4) -
+--                                                      ...
+--
+-- k = i*(n-2) - (i choose 2) + (j - 1)
+ijToKUpper :: Int -> Int -> Int -> Int
+ijToKUpper n i j
+  | i < j     = i * (n - 2) - round (i `choose` 2) + j - 1
+  | otherwise = error "ijToKUpper: not defined for lower triangular matrix."
+
+-- The function is a little weird because HMatrix uses Double indices for Matrix
+-- Double builders.
+fromListBuilderLower :: RealFrac a => [a] -> a -> a -> a
+fromListBuilderLower es i j
+  | i > j = es !! ijToKLower iI jI
+  | i == j = 0.0
+  | i < j = es !! ijToKLower jI iI
+  | otherwise = error
+    "Float indices could not be compared during matrix creation."
+ where
+  iI = round i :: Int
+  jI = round j :: Int
+
+-- The function is a little weird because HMatrix uses Double indices for Matrix
+-- Double builders.
+fromListBuilderUpper :: RealFrac a => Int -> [a] -> a -> a -> a
+fromListBuilderUpper n es i j
+  | i < j = es !! ijToKUpper n iI jI
+  | i == j = 0.0
+  | i > j = es !! ijToKUpper n jI iI
+  | otherwise = error
+    "Float indices could not be compared during matrix creation."
+ where
+  iI = round i :: Int
+  jI = round j :: Int
+
+checkEs :: RealFrac a => Int -> [a] -> [a]
+checkEs n es | length es == nExp = es
+             | otherwise         = error eStr
+ where
+  nExp = round (n `choose` 2)
+  eStr = unlines
+    [ "exchFromListlower: the number of exchangeabilities does not match the matrix size"
+    , "matrix size: " ++ show n
+    , "expected number of exchangeabilities: " ++ show nExp
+    , "received number of exchangeabilities: " ++ show (length es)
+    ]
+
+-- | Build exchangeability matrix from list denoting lower triangular matrix,
+-- and excluding diagonal. This is how the exchangeabilities are specified in
+-- PAML.
+exchFromListLower :: (RealFrac a, Container Vector a) => Int -> [a] -> Matrix a
+exchFromListLower n es = build (n, n) (fromListBuilderLower (checkEs n es))
+
+-- | Build exchangeability matrix from list denoting upper triangular matrix,
+-- and excluding diagonal.
+exchFromListUpper :: (RealFrac a, Container Vector a) => Int -> [a] -> Matrix a
+exchFromListUpper n es = build (n, n) (fromListBuilderUpper n (checkEs n es))
diff --git a/src/ELynx/Data/MarkovProcess/SubstitutionModel.hs b/src/ELynx/Data/MarkovProcess/SubstitutionModel.hs
new file mode 100644
--- /dev/null
+++ b/src/ELynx/Data/MarkovProcess/SubstitutionModel.hs
@@ -0,0 +1,143 @@
+{- |
+Module      :  ELynx.Data.MarkovProcess.SubstitutionModel
+Description :  Data type describing substitution model
+Copyright   :  (c) Dominik Schrempf 2020
+License     :  GPL-3.0-or-later
+
+Maintainer  :  dominik.schrempf@gmail.com
+Stability   :  unstable
+Portability :  portable
+
+Creation date: Tue Jan 29 19:10:46 2019.
+
+To be imported qualified.
+
+-}
+
+module ELynx.Data.MarkovProcess.SubstitutionModel
+  ( -- * Types
+    Name
+  , Params
+  , SubstitutionModel
+  -- * Lenses and other accessors
+  , alphabet
+  , name
+  , stationaryDistribution
+  , exchangeabilityMatrix
+  , rateMatrix
+  , totalRate
+  -- * Building substitution models
+  , substitutionModel
+  -- * Transformations
+  , scale
+  , normalize
+  , appendName
+  -- * Output
+  , summarize
+  )
+where
+
+import qualified Data.ByteString.Lazy.Char8    as L
+import qualified Numeric.LinearAlgebra         as LinAlg
+
+import           ELynx.Data.Alphabet.Alphabet
+
+import           ELynx.Tools
+
+import qualified ELynx.Data.MarkovProcess.RateMatrix
+                                               as R
+
+-- | Name of substitution model; abstracted and subject to change.
+type Name = String
+
+-- | Parameters of substitution model. May be the empty list.
+type Params = [Double]
+
+-- XXX: Use a proper data type. For example:
+-- data SubstitutionModelAA = LG | WAG | LG-Custom dist | ...
+-- data SubstitutionModelNuc = JC | HKY p1 p2 ... | GTR p1 p2 ...
+--
+-- I thought about this a lot, and it seems easier like it is at the moment.
+-- Since the data types are abstracted anyways, not much harm can be done. Of
+-- course, conflicting substitution models can be declared, or duplicate ones
+-- with different names, but well...
+
+-- | Complete definition of a substitution model. Create instances with
+-- 'substitutionModel'. A substitution model has an alphabet, a name, and a list
+-- of parameters (e.g., the kappa value for the HKY model). Further, the
+-- transition rate matrix is defined by a stationary distribution and a set of
+-- exchangeabilities.
+data SubstitutionModel = SubstitutionModel
+  { alphabet               :: Alphabet -- ^ Alphabet
+  , name                   :: Name     -- ^ Name
+  , params                 :: Params   -- ^ List of parameters
+  , stationaryDistribution :: R.StationaryDistribution -- ^ Stationary distribution
+  , exchangeabilityMatrix  :: R.ExchangeabilityMatrix  -- ^ Exchangeability matrix
+  }
+  deriving (Show, Read)
+
+-- | Calculate rate matrix from substitution model.
+rateMatrix :: SubstitutionModel -> R.RateMatrix
+rateMatrix sm = R.fromExchangeabilityMatrix (exchangeabilityMatrix sm)
+                                            (stationaryDistribution sm)
+
+-- | Get scale of substitution model.
+totalRate :: SubstitutionModel -> Double
+totalRate sm = R.totalRate (rateMatrix sm)
+
+-- | Create normalized 'SubstitutionModel'. See 'normalize'.
+substitutionModel
+  :: Alphabet
+  -> Name
+  -> Params
+  -> R.StationaryDistribution
+  -> R.ExchangeabilityMatrix
+  -> SubstitutionModel
+substitutionModel c n ps d e = if R.isValid d
+  then normalize $ SubstitutionModel c n ps d' e
+  else
+    error
+    $  "substitionModel: Stationary distribution does not sum to 1.0: "
+    ++ show d
+  where d' = normalizeSumVec 1.0 d
+
+-- | Scale the rate of a substitution model by given factor.
+scale :: Double -> SubstitutionModel -> SubstitutionModel
+scale r sm = sm { exchangeabilityMatrix = em' }
+  where em' = LinAlg.scale r $ exchangeabilityMatrix sm
+
+-- | Normalize a substitution model, so that, on average, one substitution
+-- happens per unit time.
+normalize :: SubstitutionModel -> SubstitutionModel
+normalize sm = scale (1.0 / r) sm where r = totalRate sm
+
+-- | Abbend to name.
+appendName :: Name -> SubstitutionModel -> SubstitutionModel
+appendName n sm = sm { name = n' } where n' = name sm <> n
+
+-- | Summarize a substitution model; lines to be printed to screen or log.
+summarize :: SubstitutionModel -> [L.ByteString]
+summarize sm =
+  map L.pack
+    $  (show (alphabet sm) ++ " substitution model: " ++ name sm ++ ".")
+    :  [ "Parameters: " ++ show (params sm) ++ "." | not (null (params sm)) ]
+    ++ case alphabet sm of
+         DNA ->
+           [ "Stationary distribution: "
+             ++ dispv precision (stationaryDistribution sm)
+             ++ "."
+           , "Exchangeability matrix:\n"
+             ++ dispmi 2 precision (exchangeabilityMatrix sm)
+             ++ "."
+           , "Scale: " ++ show (roundN precision $ totalRate sm) ++ "."
+           ]
+         Protein ->
+           [ "Stationary distribution: "
+             ++ dispv precision (stationaryDistribution sm)
+             ++ "."
+           , "Scale: " ++ show (roundN precision $ totalRate sm) ++ "."
+           ]
+         _ ->
+           error
+             "Extended character sets are not supported with substitution models."
+
diff --git a/src/ELynx/Import/MarkovProcess/EDMModelPhylobayes.hs b/src/ELynx/Import/MarkovProcess/EDMModelPhylobayes.hs
new file mode 100644
--- /dev/null
+++ b/src/ELynx/Import/MarkovProcess/EDMModelPhylobayes.hs
@@ -0,0 +1,75 @@
+{- |
+Module      :  ELynx.Import.MarkovProcess.EDMModelPhylobayes
+Description :  Import stationary distributions from Phylobayes format
+Copyright   :  (c) Dominik Schrempf 2020
+License     :  GPL-3.0-or-later
+
+Maintainer  :  dominik.schrempf@gmail.com
+Stability   :  unstable
+Portability :  portable
+
+Creation date: Tue Jan 29 12:12:55 2019.
+
+-}
+
+module ELynx.Import.MarkovProcess.EDMModelPhylobayes
+  ( Parser
+  , EDMComponent
+  , phylobayes
+  )
+where
+
+import           Control.Monad
+import qualified Data.ByteString.Lazy.Char8    as L
+import qualified Data.Vector.Storable          as V
+import           Data.Void
+import           Text.Megaparsec
+import           Text.Megaparsec.Byte
+import           Text.Megaparsec.Byte.Lexer
+
+import           ELynx.Data.MarkovProcess.MixtureModel
+                                                ( Weight )
+
+import           ELynx.Tools
+
+-- | Shortcut.
+type Parser = Parsec Void L.ByteString
+
+-- | An empirical mixture model component has a weight and a stationary
+-- distribution.
+type EDMComponent = (Weight, V.Vector Double)
+
+-- | Parse stationary distributions from Phylobayes format.
+phylobayes :: Parser [EDMComponent]
+phylobayes = do
+  n  <- headerLine
+  k  <- kComponentsLine
+  cs <- count k $ dataLine n
+  _  <- many newline *> eof <?> "phylobayes"
+  return cs
+
+horizontalSpace :: Parser ()
+horizontalSpace = skipMany $ char (c2w ' ') <|> tab
+
+headerLine :: Parser Int
+headerLine = do
+  n <- decimal
+  _ <- horizontalSpace
+  -- FIXME: This should be more general, but then we also want to ensure that
+  -- the order of states is correct.
+  _ <- chunk (L.pack "A C D E F G H I K L M N P Q R S T V W Y")
+    <|> chunk (L.pack "A C G T")
+  _ <- many newline <?> "headerLine"
+  return n
+
+kComponentsLine :: Parser Int
+kComponentsLine = decimal <* newline <?> "kComponentsLine"
+
+dataLine :: Int -> Parser EDMComponent
+dataLine n = do
+  weight <- float
+  _      <- horizontalSpace
+  vals   <- float `sepBy` horizontalSpace
+  when (length vals /= n) (error "Did not find correct number of entries.")
+  _ <- many newline <?> "dataLine"
+  return (weight, V.fromList vals)
diff --git a/src/ELynx/Import/MarkovProcess/SiteprofilesPhylobayes.hs b/src/ELynx/Import/MarkovProcess/SiteprofilesPhylobayes.hs
new file mode 100644
--- /dev/null
+++ b/src/ELynx/Import/MarkovProcess/SiteprofilesPhylobayes.hs
@@ -0,0 +1,77 @@
+{- |
+Module      :  ELynx.Import.MarkovProcess.SiteprofilesPhylobayes
+Description :  Import site profiles in Phylobayes format
+Copyright   :  (c) Dominik Schrempf 2020
+License     :  GPL-3.0-or-later
+
+Maintainer  :  dominik.schrempf@gmail.com
+Stability   :  unstable
+Portability :  portable
+
+Creation date: Tue Jan 29 12:12:55 2019.
+
+For now I just try to go with a huge empirical distribution mixture model. Let's
+see if performance is good enough.
+
+There are subtle differences between
+`ELynx.Import.MarkovProcess.EDMModelPhylobayes` and this module, which collects
+one stationary distribution for each site.
+
+-}
+
+module ELynx.Import.MarkovProcess.SiteprofilesPhylobayes
+  ( siteprofiles
+  )
+where
+
+import           Control.Monad
+import           Data.List                      ( nub )
+import qualified Data.Vector.Storable          as V
+import           Text.Megaparsec
+import           Text.Megaparsec.Byte
+import           Text.Megaparsec.Byte.Lexer
+
+import           ELynx.Tools
+
+import           ELynx.Import.MarkovProcess.EDMModelPhylobayes
+                                                ( Parser
+                                                , EDMComponent
+                                                )
+
+-- | Parse stationary distributions from Phylobayes format.
+siteprofiles :: Parser [EDMComponent]
+siteprofiles = do
+  _  <- headerLines
+  cs <- many dataLine
+  _  <- many newline *> eof <?> "phylobayes siteprofiles"
+  let ls  = map length cs
+      nLs = length $ nub ls
+  when (nLs /= 1)
+       (error "The site profiles have a different number of entries.")
+  return cs
+
+horizontalSpace :: Parser ()
+horizontalSpace = skipMany $ char (c2w ' ') <|> tab
+
+line :: Parser ()
+line = do
+  _ <- many $ noneOf [c2w '\n']
+  pure ()
+
+-- For now, just ignore the header.
+headerLines :: Parser ()
+headerLines = do
+  _ <- line
+  _ <- many newline <?> "headerLine"
+  pure ()
+
+dataLine :: Parser EDMComponent
+dataLine = do
+  -- Ignore site number.
+  _    <- decimal :: Parser Integer
+  _    <- horizontalSpace
+  -- Also ignore additional white space on line.
+  vals <- float `sepEndBy1` horizontalSpace
+  _    <- many newline <?> "dataLine"
+  -- Set the weight to 1.0 for all sites.
+  return (1.0, V.fromList vals)
diff --git a/src/ELynx/Simulate/MarkovProcess.hs b/src/ELynx/Simulate/MarkovProcess.hs
new file mode 100644
--- /dev/null
+++ b/src/ELynx/Simulate/MarkovProcess.hs
@@ -0,0 +1,78 @@
+{- |
+Module      :  ELynx.Simulate.MarkovProcess
+Description :  Markov process helpers
+Copyright   :  (c) Dominik Schrempf 2020
+License     :  GPL-3.0-or-later
+
+Maintainer  :  dominik.schrempf@gmail.com
+Stability   :  unstable
+Portability :  portable
+
+Creation date: Thu Jan 24 09:02:25 2019.
+
+-}
+
+module ELynx.Simulate.MarkovProcess
+  ( ProbMatrix
+  , State
+  , probMatrix
+  , jump
+  )
+where
+
+import           Control.Monad.Primitive
+import           Numeric.LinearAlgebra
+import           System.Random.MWC
+import           System.Random.MWC.Distributions
+
+import           ELynx.Data.MarkovProcess.RateMatrix
+
+-- | A probability matrix, P_ij(t) = Pr (X_t = j | X_0 = i).
+type ProbMatrix = Matrix R
+
+-- | Make type signatures a little clearer.
+type State = Int
+
+-- | The important matrix that gives the probabilities to move from one state to
+-- another in a specific time (branch length).
+probMatrix :: RateMatrix -> Double -> ProbMatrix
+probMatrix q t
+  | t == 0 = if rows q == cols q
+    then ident (rows q)
+    else error "probMatrix: Matrix is not square."
+  | t < 0 = error "probMatrix: Time is negative."
+  | otherwise = expm $ scale t q
+
+-- | Move from a given state to a new one according to a transition probability
+-- matrix (for performance reasons this probability matrix needs to be given as
+-- a list of generators, see
+-- https://hackage.haskell.org/package/distribution-1.1.0.0/docs/Data-Distribution-Sample.html).
+-- This function is the bottleneck of the simulator and takes up most of the
+-- computation time. However, I was not able to find a faster implementation
+-- than the one from Data.Distribution.
+jump :: (PrimMonad m) => State -> ProbMatrix -> Gen (PrimState m) -> m State
+jump i p = categorical (p ! i)
+
+-- XXX: Maybe for later, use condensed tables.
+--
+-- Write storable instance, compilation is really slow otherwise. instance
+-- Storable (Int, R) where sizeOf (x, y) = sizeOf x + sizeOf y
+--
+-- Do not generate table for each jump.
+--
+-- jump :: (PrimMonad m) => State -> ProbMatrix -> Gen (PrimState m) -> m State
+-- jump i p = genFromTable table
+--   where
+--     ws = toList $ p ! i
+--     vsAndWs = fromList [ (v, w) | (v, w) <- zip [(0 :: Int) ..] ws
+--                                 , w > 0 ]
+--     table = tableFromProbabilities vsAndWs
+
+-- -- | Perform N jumps from a given state and according to a transition
+-- -- probability matrix transformed to a list of generators. This implementation
+-- -- uses 'foldM' and I am not sure how to access or store the actual chain. This
+-- -- could be done by an equivalent of 'scanl' for general monads, which I was
+-- -- unable to find. This function is neat, but will most likely not be needed.
+-- -- However, it is instructive and is left in place.
+-- jumpN :: (MonadRandom m) => State -> [Generator State] -> Int -> m State
+-- jumpN s p n = foldM jump s (replicate n p)
diff --git a/src/ELynx/Simulate/MarkovProcessAlongTree.hs b/src/ELynx/Simulate/MarkovProcessAlongTree.hs
new file mode 100644
--- /dev/null
+++ b/src/ELynx/Simulate/MarkovProcessAlongTree.hs
@@ -0,0 +1,222 @@
+{- |
+   Description :  Work with transition probability matrices on rooted trees
+   Copyright   :  (c) Dominik Schrempf 2017
+   License     :  GPLv3
+
+   Maintainer  :  dominik.schrempf@gmail.com
+   Stability   :  unstable
+   Portability :  non-portable (not tested)
+
+Calculate transition probability matrices, map rate matrices on trees, populate
+a tree with states according to a stationary distribution, etc.
+
+The implementation of the Markov process is more than basic and can be improved
+in a lot of ways.
+
+-}
+
+module ELynx.Simulate.MarkovProcessAlongTree
+  ( -- * Single rate matrix.
+    simulate
+  , simulateAndFlatten
+    -- * Mixture models.
+  , simulateMixtureModel
+  , simulateAndFlattenMixtureModel
+  , simulateAndFlattenMixtureModelPar
+  )
+where
+
+import           Control.Monad
+import           Control.Monad.Primitive
+import           Control.Parallel.Strategies
+import           Data.Tree
+import           Numeric.LinearAlgebra
+import           System.Random.MWC              ( Gen
+                                                , GenIO
+                                                )
+import           System.Random.MWC.Distributions
+                                                ( categorical )
+
+import           ELynx.Data.Tree
+
+import           ELynx.Tools
+
+import           ELynx.Data.MarkovProcess.RateMatrix
+import           ELynx.Simulate.MarkovProcess
+
+toProbTree :: (Measurable a) => RateMatrix -> Tree a -> Tree ProbMatrix
+toProbTree q = fmap (probMatrix q . getLen)
+
+getRootStates
+  :: PrimMonad m
+  => Int
+  -> StationaryDistribution
+  -> Gen (PrimState m)
+  -> m [State]
+getRootStates n d g = replicateM n $ categorical d g
+
+-- | Simulate a number of sites for a given substitution model. Only the states
+-- at the leafs are retained. The states at internal nodes are removed. This has
+-- a lower memory footprint.
+--
+-- XXX: Improve performance. Use vectors, not lists.
+simulateAndFlatten
+  :: (PrimMonad m, Measurable a)
+  => Int
+  -> StationaryDistribution
+  -> ExchangeabilityMatrix
+  -> Tree a
+  -> Gen (PrimState m)
+  -> m [[State]]
+simulateAndFlatten n d e t g = do
+  let q  = fromExchangeabilityMatrix e d
+      pt = toProbTree q t
+  is <- getRootStates n d g
+  simulateAndFlatten' is pt g
+
+-- This is the heart of the simulation. Take a tree and a list of root states.
+-- Recursively jump down the branches to the leafs. Forget states at internal.
+simulateAndFlatten'
+  :: (PrimMonad m)
+  => [State]
+  -> Tree ProbMatrix
+  -> Gen (PrimState m)
+  -> m [[State]]
+simulateAndFlatten' is (Node p f) g = do
+  is' <- mapM (\i -> jump i p g) is
+  if null f
+    then return [is']
+    else concat <$> sequence [ simulateAndFlatten' is' t g | t <- f ]
+
+-- | Simulate a number of sites for a given substitution model. Keep states at
+-- internal nodes. The result is a tree with the list of simulated states as
+-- node labels.
+simulate
+  :: (PrimMonad m, Measurable a)
+  => Int
+  -> StationaryDistribution
+  -> ExchangeabilityMatrix
+  -> Tree a
+  -> Gen (PrimState m)
+  -> m (Tree [State])
+simulate n d e t g = do
+  let q  = fromExchangeabilityMatrix e d
+      pt = toProbTree q t
+  is <- getRootStates n d g
+  simulate' is pt g
+
+-- This is the heart of the simulation. Take a tree and a list of root states.
+-- Recursively jump down the branches to the leafs.
+simulate'
+  :: (PrimMonad m)
+  => [State]
+  -> Tree ProbMatrix
+  -> Gen (PrimState m)
+  -> m (Tree [State])
+simulate' is (Node p f) g = do
+  is' <- mapM (\i -> jump i p g) is
+  f'  <- sequence [ simulate' is' t g | t <- f ]
+  return $ Node is' f'
+
+toProbTreeMixtureModel
+  :: (Measurable a) => [RateMatrix] -> Tree a -> Tree [ProbMatrix]
+toProbTreeMixtureModel qs =
+  fmap (\a -> [ probMatrix q . getLen $ a | q <- qs ] `using` parList rpar)
+
+getComponentsAndRootStates
+  :: PrimMonad m
+  => Int
+  -> Vector R
+  -> [StationaryDistribution]
+  -> Gen (PrimState m)
+  -> m ([Int], [State])
+getComponentsAndRootStates n ws ds g = do
+  cs <- replicateM n $ categorical ws g
+  is <- sequence [ categorical (ds !! c) g | c <- cs ]
+  return (cs, is)
+
+-- | Simulate a number of sites for a given set of substitution models with
+-- corresponding weights. Forget states at internal nodes. See also
+-- 'simulateAndFlatten'.
+simulateAndFlattenMixtureModel
+  :: (PrimMonad m, Measurable a)
+  => Int
+  -> Vector R
+  -> [StationaryDistribution]
+  -> [ExchangeabilityMatrix]
+  -> Tree a
+  -> Gen (PrimState m)
+  -> m [[State]]
+simulateAndFlattenMixtureModel n ws ds es t g = do
+  let qs = zipWith fromExchangeabilityMatrix es ds
+      pt = toProbTreeMixtureModel qs t
+  (cs, is) <- getComponentsAndRootStates n ws ds g
+  simulateAndFlattenMixtureModel' is cs pt g
+
+simulateAndFlattenMixtureModel'
+  :: (PrimMonad m)
+  => [State]
+  -> [Int]
+  -> Tree [ProbMatrix]
+  -> Gen (PrimState m)
+  -> m [[State]]
+simulateAndFlattenMixtureModel' is cs (Node ps f) g = do
+  is' <- sequence [ jump i (ps !! c) g | (i, c) <- zip is cs ]
+  if null f
+    then return [is']
+    else concat
+      <$> sequence [ simulateAndFlattenMixtureModel' is' cs t g | t <- f ]
+
+-- | See 'simulateAndFlattenMixtureModel', parallel version;
+-- needs to be run in IO monad.
+simulateAndFlattenMixtureModelPar
+  :: Measurable a
+  => Int
+  -> Vector R
+  -> [StationaryDistribution]
+  -> [ExchangeabilityMatrix]
+  -> Tree a
+  -> GenIO
+  -> IO [[[State]]]
+simulateAndFlattenMixtureModelPar n ws ds es t g = do
+  let qs = zipWith fromExchangeabilityMatrix es ds
+      pt = toProbTreeMixtureModel qs t
+  parComp
+    n
+    (\n' g' -> do
+      (cs, is) <- getComponentsAndRootStates n' ws ds g'
+      simulateAndFlattenMixtureModel' is cs pt g'
+    )
+    g
+
+-- | Simulate a number of sites for a given set of substitution models with
+-- corresponding weights. Keep states at internal nodes. See also
+-- 'simulate'.
+simulateMixtureModel
+  :: (PrimMonad m, Measurable a)
+  => Int
+  -> Vector R
+  -> [StationaryDistribution]
+  -> [ExchangeabilityMatrix]
+  -> Tree a
+  -> Gen (PrimState m)
+  -> m (Tree [State])
+simulateMixtureModel n ws ds es t g = do
+  let qs = zipWith fromExchangeabilityMatrix es ds
+      pt = toProbTreeMixtureModel qs t
+  (cs, is) <- getComponentsAndRootStates n ws ds g
+  simulateMixtureModel' is cs pt g
+
+-- See 'simulateAlongProbTree', only we have a number of mixture components. The
+-- starting states and the components for each site have to be provided.
+simulateMixtureModel'
+  :: (PrimMonad m)
+  => [State]
+  -> [Int]
+  -> Tree [ProbMatrix]
+  -> Gen (PrimState m)
+  -> m (Tree [State])
+simulateMixtureModel' is cs (Node ps f) g = do
+  is' <- sequence [ jump i (ps !! c) g | (i, c) <- zip is cs ]
+  f'  <- sequence [ simulateMixtureModel' is' cs t g | t <- f ]
+  return $ Node is' f'
diff --git a/test/ELynx/Data/MarkovProcess/AminoAcidSpec.hs b/test/ELynx/Data/MarkovProcess/AminoAcidSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/ELynx/Data/MarkovProcess/AminoAcidSpec.hs
@@ -0,0 +1,525 @@
+{- |
+Module      :  ELynx.Data.MarkovProcess.AminoAcidSpec
+Copyright   :  (c) Dominik Schrempf 2020
+License     :  GPL-3.0-or-later
+
+Maintainer  :  dominik.schrempf@gmail.com
+Stability   :  unstable
+Portability :  portable
+
+Creation date: Tue Jan 29 10:47:40 2019.
+
+-}
+
+module ELynx.Data.MarkovProcess.AminoAcidSpec
+  ( spec
+  )
+where
+
+import           Numeric.LinearAlgebra
+import           Test.Hspec
+
+import           ELynx.Tools
+
+import           ELynx.Data.MarkovProcess.AminoAcid
+import qualified ELynx.Data.MarkovProcess.RateMatrix
+                                               as R
+import qualified ELynx.Data.MarkovProcess.SubstitutionModel
+                                               as S
+
+statDistLGPython :: R.StationaryDistribution
+statDistLGPython = normalizeSumVec 1.0 $ fromList
+  [ 0.079066
+  , 0.012937
+  , 0.053052
+  , 0.071586
+  , 0.042302
+  , 0.057337
+  , 0.022355
+  , 0.062157
+  , 0.064600
+  , 0.099081
+  , 0.022951
+  , 0.041977
+  , 0.044040
+  , 0.040767
+  , 0.055941
+  , 0.061197
+  , 0.053287
+  , 0.069147
+  , 0.012066
+  , 0.034155
+  ]
+
+exchLGPython :: R.ExchangeabilityMatrix
+exchLGPython = fromLists
+  [ [ 0.0000000e+00
+    , 2.4890840e+00
+    , 3.9514400e-01
+    , 1.0385450e+00
+    , 2.5370100e-01
+    , 2.0660400e+00
+    , 3.5885800e-01
+    , 1.4983000e-01
+    , 5.3651800e-01
+    , 3.9533700e-01
+    , 1.1240350e+00
+    , 2.7681800e-01
+    , 1.1776510e+00
+    , 9.6989400e-01
+    , 4.2509300e-01
+    , 4.7271820e+00
+    , 2.1395010e+00
+    , 2.5478700e+00
+    , 1.8071700e-01
+    , 2.1895900e-01
+    ]
+  , [ 2.4890840e+00
+    , 0.0000000e+00
+    , 6.2556000e-02
+    , 3.4990000e-03
+    , 1.1052510e+00
+    , 5.6926500e-01
+    , 6.4054300e-01
+    , 3.2062700e-01
+    , 1.3266000e-02
+    , 5.9400700e-01
+    , 8.9368000e-01
+    , 5.2876800e-01
+    , 7.5382000e-02
+    , 8.4808000e-02
+    , 5.3455100e-01
+    , 2.7844780e+00
+    , 1.1434800e+00
+    , 1.9592910e+00
+    , 6.7012800e-01
+    , 1.1655320e+00
+    ]
+  , [ 3.9514400e-01
+    , 6.2556000e-02
+    , 0.0000000e+00
+    , 5.2438700e+00
+    , 1.7416000e-02
+    , 8.4492600e-01
+    , 9.2711400e-01
+    , 1.0690000e-02
+    , 2.8295900e-01
+    , 1.5076000e-02
+    , 2.5548000e-02
+    , 5.0761490e+00
+    , 3.9445600e-01
+    , 5.2338600e-01
+    , 1.2395400e-01
+    , 1.2402750e+00
+    , 4.2586000e-01
+    , 3.7967000e-02
+    , 2.9890000e-02
+    , 1.3510700e-01
+    ]
+  , [ 1.0385450e+00
+    , 3.4990000e-03
+    , 5.2438700e+00
+    , 0.0000000e+00
+    , 1.8811000e-02
+    , 3.4884700e-01
+    , 4.2388100e-01
+    , 4.4265000e-02
+    , 1.8071770e+00
+    , 6.9673000e-02
+    , 1.7373500e-01
+    , 5.4171200e-01
+    , 4.1940900e-01
+    , 4.1285910e+00
+    , 3.6397000e-01
+    , 6.1197300e-01
+    , 6.0454500e-01
+    , 2.4503400e-01
+    , 7.7852000e-02
+    , 1.2003700e-01
+    ]
+  , [ 2.5370100e-01
+    , 1.1052510e+00
+    , 1.7416000e-02
+    , 1.8811000e-02
+    , 0.0000000e+00
+    , 8.9586000e-02
+    , 6.8213900e-01
+    , 1.1127270e+00
+    , 2.3918000e-02
+    , 2.5926920e+00
+    , 1.7988530e+00
+    , 8.9525000e-02
+    , 9.4464000e-02
+    , 3.5855000e-02
+    , 5.2722000e-02
+    , 3.6181900e-01
+    , 1.6500100e-01
+    , 6.5468300e-01
+    , 2.4571210e+00
+    , 7.8039020e+00
+    ]
+  , [ 2.0660400e+00
+    , 5.6926500e-01
+    , 8.4492600e-01
+    , 3.4884700e-01
+    , 8.9586000e-02
+    , 0.0000000e+00
+    , 3.1148400e-01
+    , 8.7050000e-03
+    , 2.9663600e-01
+    , 4.4261000e-02
+    , 1.3953800e-01
+    , 1.4376450e+00
+    , 1.9696100e-01
+    , 2.6795900e-01
+    , 3.9019200e-01
+    , 1.7399900e+00
+    , 1.2983600e-01
+    , 7.6701000e-02
+    , 2.6849100e-01
+    , 5.4679000e-02
+    ]
+  , [ 3.5885800e-01
+    , 6.4054300e-01
+    , 9.2711400e-01
+    , 4.2388100e-01
+    , 6.8213900e-01
+    , 3.1148400e-01
+    , 0.0000000e+00
+    , 1.0888200e-01
+    , 6.9726400e-01
+    , 3.6631700e-01
+    , 4.4247200e-01
+    , 4.5092380e+00
+    , 5.0885100e-01
+    , 4.8135050e+00
+    , 2.4266010e+00
+    , 9.9001200e-01
+    , 5.8426200e-01
+    , 1.1901300e-01
+    , 5.9705400e-01
+    , 5.3068340e+00
+    ]
+  , [ 1.4983000e-01
+    , 3.2062700e-01
+    , 1.0690000e-02
+    , 4.4265000e-02
+    , 1.1127270e+00
+    , 8.7050000e-03
+    , 1.0888200e-01
+    , 0.0000000e+00
+    , 1.5906900e-01
+    , 4.1450670e+00
+    , 4.2736070e+00
+    , 1.9150300e-01
+    , 7.8281000e-02
+    , 7.2854000e-02
+    , 1.2699100e-01
+    , 6.4105000e-02
+    , 1.0337390e+00
+    , 1.0649107e+01
+    , 1.1166000e-01
+    , 2.3252300e-01
+    ]
+  , [ 5.3651800e-01
+    , 1.3266000e-02
+    , 2.8295900e-01
+    , 1.8071770e+00
+    , 2.3918000e-02
+    , 2.9663600e-01
+    , 6.9726400e-01
+    , 1.5906900e-01
+    , 0.0000000e+00
+    , 1.3750000e-01
+    , 6.5660400e-01
+    , 2.1450780e+00
+    , 3.9032200e-01
+    , 3.2342940e+00
+    , 6.3260670e+00
+    , 7.4868300e-01
+    , 1.1368630e+00
+    , 1.8520200e-01
+    , 4.9906000e-02
+    , 1.3193200e-01
+    ]
+  , [ 3.9533700e-01
+    , 5.9400700e-01
+    , 1.5076000e-02
+    , 6.9673000e-02
+    , 2.5926920e+00
+    , 4.4261000e-02
+    , 3.6631700e-01
+    , 4.1450670e+00
+    , 1.3750000e-01
+    , 0.0000000e+00
+    , 6.3123580e+00
+    , 6.8427000e-02
+    , 2.4906000e-01
+    , 5.8245700e-01
+    , 3.0184800e-01
+    , 1.8228700e-01
+    , 3.0293600e-01
+    , 1.7027450e+00
+    , 6.1963200e-01
+    , 2.9964800e-01
+    ]
+  , [ 1.1240350e+00
+    , 8.9368000e-01
+    , 2.5548000e-02
+    , 1.7373500e-01
+    , 1.7988530e+00
+    , 1.3953800e-01
+    , 4.4247200e-01
+    , 4.2736070e+00
+    , 6.5660400e-01
+    , 6.3123580e+00
+    , 0.0000000e+00
+    , 3.7100400e-01
+    , 9.9849000e-02
+    , 1.6725690e+00
+    , 4.8413300e-01
+    , 3.4696000e-01
+    , 2.0203660e+00
+    , 1.8987180e+00
+    , 6.9617500e-01
+    , 4.8130600e-01
+    ]
+  , [ 2.7681800e-01
+    , 5.2876800e-01
+    , 5.0761490e+00
+    , 5.4171200e-01
+    , 8.9525000e-02
+    , 1.4376450e+00
+    , 4.5092380e+00
+    , 1.9150300e-01
+    , 2.1450780e+00
+    , 6.8427000e-02
+    , 3.7100400e-01
+    , 0.0000000e+00
+    , 1.6178700e-01
+    , 1.6957520e+00
+    , 7.5187800e-01
+    , 4.0083580e+00
+    , 2.0006790e+00
+    , 8.3688000e-02
+    , 4.5376000e-02
+    , 6.1202500e-01
+    ]
+  , [ 1.1776510e+00
+    , 7.5382000e-02
+    , 3.9445600e-01
+    , 4.1940900e-01
+    , 9.4464000e-02
+    , 1.9696100e-01
+    , 5.0885100e-01
+    , 7.8281000e-02
+    , 3.9032200e-01
+    , 2.4906000e-01
+    , 9.9849000e-02
+    , 1.6178700e-01
+    , 0.0000000e+00
+    , 6.2429400e-01
+    , 3.3253300e-01
+    , 1.3381320e+00
+    , 5.7146800e-01
+    , 2.9650100e-01
+    , 9.5131000e-02
+    , 8.9613000e-02
+    ]
+  , [ 9.6989400e-01
+    , 8.4808000e-02
+    , 5.2338600e-01
+    , 4.1285910e+00
+    , 3.5855000e-02
+    , 2.6795900e-01
+    , 4.8135050e+00
+    , 7.2854000e-02
+    , 3.2342940e+00
+    , 5.8245700e-01
+    , 1.6725690e+00
+    , 1.6957520e+00
+    , 6.2429400e-01
+    , 0.0000000e+00
+    , 2.8079080e+00
+    , 1.2238280e+00
+    , 1.0801360e+00
+    , 2.1033200e-01
+    , 2.3619900e-01
+    , 2.5733600e-01
+    ]
+  , [ 4.2509300e-01
+    , 5.3455100e-01
+    , 1.2395400e-01
+    , 3.6397000e-01
+    , 5.2722000e-02
+    , 3.9019200e-01
+    , 2.4266010e+00
+    , 1.2699100e-01
+    , 6.3260670e+00
+    , 3.0184800e-01
+    , 4.8413300e-01
+    , 7.5187800e-01
+    , 3.3253300e-01
+    , 2.8079080e+00
+    , 0.0000000e+00
+    , 8.5815100e-01
+    , 5.7898700e-01
+    , 1.7088700e-01
+    , 5.9360700e-01
+    , 3.1444000e-01
+    ]
+  , [ 4.7271820e+00
+    , 2.7844780e+00
+    , 1.2402750e+00
+    , 6.1197300e-01
+    , 3.6181900e-01
+    , 1.7399900e+00
+    , 9.9001200e-01
+    , 6.4105000e-02
+    , 7.4868300e-01
+    , 1.8228700e-01
+    , 3.4696000e-01
+    , 4.0083580e+00
+    , 1.3381320e+00
+    , 1.2238280e+00
+    , 8.5815100e-01
+    , 0.0000000e+00
+    , 6.4722790e+00
+    , 9.8369000e-02
+    , 2.4886200e-01
+    , 4.0054700e-01
+    ]
+  , [ 2.1395010e+00
+    , 1.1434800e+00
+    , 4.2586000e-01
+    , 6.0454500e-01
+    , 1.6500100e-01
+    , 1.2983600e-01
+    , 5.8426200e-01
+    , 1.0337390e+00
+    , 1.1368630e+00
+    , 3.0293600e-01
+    , 2.0203660e+00
+    , 2.0006790e+00
+    , 5.7146800e-01
+    , 1.0801360e+00
+    , 5.7898700e-01
+    , 6.4722790e+00
+    , 0.0000000e+00
+    , 2.1881580e+00
+    , 1.4082500e-01
+    , 2.4584100e-01
+    ]
+  , [ 2.5478700e+00
+    , 1.9592910e+00
+    , 3.7967000e-02
+    , 2.4503400e-01
+    , 6.5468300e-01
+    , 7.6701000e-02
+    , 1.1901300e-01
+    , 1.0649107e+01
+    , 1.8520200e-01
+    , 1.7027450e+00
+    , 1.8987180e+00
+    , 8.3688000e-02
+    , 2.9650100e-01
+    , 2.1033200e-01
+    , 1.7088700e-01
+    , 9.8369000e-02
+    , 2.1881580e+00
+    , 0.0000000e+00
+    , 1.8951000e-01
+    , 2.4931300e-01
+    ]
+  , [ 1.8071700e-01
+    , 6.7012800e-01
+    , 2.9890000e-02
+    , 7.7852000e-02
+    , 2.4571210e+00
+    , 2.6849100e-01
+    , 5.9705400e-01
+    , 1.1166000e-01
+    , 4.9906000e-02
+    , 6.1963200e-01
+    , 6.9617500e-01
+    , 4.5376000e-02
+    , 9.5131000e-02
+    , 2.3619900e-01
+    , 5.9360700e-01
+    , 2.4886200e-01
+    , 1.4082500e-01
+    , 1.8951000e-01
+    , 0.0000000e+00
+    , 3.1518150e+00
+    ]
+  , [ 2.1895900e-01
+    , 1.1655320e+00
+    , 1.3510700e-01
+    , 1.2003700e-01
+    , 7.8039020e+00
+    , 5.4679000e-02
+    , 5.3068340e+00
+    , 2.3252300e-01
+    , 1.3193200e-01
+    , 2.9964800e-01
+    , 4.8130600e-01
+    , 6.1202500e-01
+    , 8.9613000e-02
+    , 2.5733600e-01
+    , 3.1444000e-01
+    , 4.0054700e-01
+    , 2.4584100e-01
+    , 2.4931300e-01
+    , 3.1518150e+00
+    , 0.0000000e+00
+    ]
+  ]
+
+statDistUniform :: R.StationaryDistribution
+statDistUniform = vector $ replicate 20 0.05
+
+statDistLG :: R.StationaryDistribution
+statDistLG = S.stationaryDistribution lg
+
+exchLG :: R.ExchangeabilityMatrix
+exchLG = S.exchangeabilityMatrix lg
+
+rmLG :: R.RateMatrix
+rmLG = S.rateMatrix lg
+
+spec :: Spec
+spec = do
+  describe "statDistLG"
+    $             it "matches distribution from python library"
+    $             statDistLG
+    `nearlyEqVec` statDistLGPython
+    `shouldBe`    True
+
+  describe "exchLG"
+    $ it "matches exchangeability matrix from python library"
+    $ do
+        exchLG `shouldSatisfy` nearlyEqMatWith 1e-4 exchLGPython
+        exchLG `nearlyEqMat` rmLG `shouldBe` False
+
+  describe "lg"
+    $ it "stationary distribution can be extracted"
+    $ nearlyEqVecWith 1e-4 (R.getStationaryDistribution rmLG) statDistLG
+    `shouldBe` True
+
+  describe "lgCustom" $ it "stationary distribution can be recovered" $ do
+    let f = R.getStationaryDistribution $ S.rateMatrix $ lgCustom
+          Nothing
+          statDistUniform
+    f `nearlyEqVec` statDistUniform `shouldBe` True
+
+  describe "poisson"
+    $             it "stationary distribution is uniform 1/20"
+    $             R.getStationaryDistribution (S.rateMatrix poisson)
+    `nearlyEqVec` statDistUniform
+    `shouldBe`    True
+
+  describe "poissonCustom" $ it "stationary distribution can be recovered" $ do
+    let f = R.getStationaryDistribution $ S.rateMatrix $ poissonCustom
+          Nothing
+          statDistLGPython
+    f `nearlyEqVec` statDistLGPython `shouldBe` True
diff --git a/test/ELynx/Data/MarkovProcess/NucleotideSpec.hs b/test/ELynx/Data/MarkovProcess/NucleotideSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/ELynx/Data/MarkovProcess/NucleotideSpec.hs
@@ -0,0 +1,40 @@
+{- |
+Module      :  ELynx.Data.MarkovProcess.NucleotideSpec
+Copyright   :  (c) Dominik Schrempf 2020
+License     :  GPL-3.0-or-later
+
+Maintainer  :  dominik.schrempf@gmail.com
+Stability   :  unstable
+Portability :  portable
+
+Creation date: Fri Jan 25 16:47:28 2019.
+
+-}
+
+module ELynx.Data.MarkovProcess.NucleotideSpec
+  ( spec
+  )
+where
+
+import           Data.Vector.Generic
+import           Test.Hspec
+
+import           ELynx.Tools
+
+import           ELynx.Data.MarkovProcess.Nucleotide
+import           ELynx.Data.MarkovProcess.RateMatrix
+import           ELynx.Data.MarkovProcess.SubstitutionModel
+
+stationaryDist :: StationaryDistribution
+stationaryDist = fromList [0.2, 0.3, 0.3, 0.2]
+
+hkyModel :: SubstitutionModel
+hkyModel = hky 6.0 stationaryDist
+
+spec :: Spec
+spec =
+  describe "getStationaryDistribution"
+    $ it "extracts the stationary distribution from a rate matrix"
+    $ do
+        let sd = getStationaryDistribution (rateMatrix hkyModel)
+        sd `nearlyEqVec` stationaryDist `shouldBe` True
diff --git a/test/ELynx/Data/MarkovProcess/RateMatrixSpec.hs b/test/ELynx/Data/MarkovProcess/RateMatrixSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/ELynx/Data/MarkovProcess/RateMatrixSpec.hs
@@ -0,0 +1,49 @@
+{- |
+Module      :  ELynx.Data.MarkovProcess.RateMatrixSpec
+Description :  Unit tests for rate matrices
+Copyright   :  (c) Dominik Schrempf 2020
+License     :  GPL-3.0-or-later
+
+Maintainer  :  dominik.schrempf@gmail.com
+Stability   :  unstable
+Portability :  portable
+
+Creation date: Fri Apr 17 15:18:02 2020.
+
+-}
+
+module ELynx.Data.MarkovProcess.RateMatrixSpec
+  ( spec
+  )
+where
+
+import           Numeric.LinearAlgebra
+import           Test.Hspec
+
+import           ELynx.Data.MarkovProcess.RateMatrix
+                                                ( exchFromListLower
+                                                , exchFromListUpper
+                                                )
+
+es :: [Double]
+es = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+
+exMLower :: Matrix R
+exMLower = (5 >< 5)
+  [0, 1, 2, 4, 7, 1, 0, 3, 5, 8, 2, 3, 0, 6, 9, 4, 5, 6, 0, 10, 7, 8, 9, 10, 0]
+
+exMUpper :: Matrix R
+exMUpper = (5 >< 5)
+  [0, 1, 2, 3, 4, 1, 0, 5, 6, 7, 2, 5, 0, 8, 9, 3, 6, 8, 0, 10, 4, 7, 9, 10, 0]
+
+spec :: Spec
+spec = do
+  describe "exchFromListLower"
+    $          it "correctly converts to matrix from list"
+    $          exMLower
+    `shouldBe` exchFromListLower 5 es
+  describe "exchFromListUpper"
+    $          it "correctly converts to matrix from list"
+    $          exMUpper
+    `shouldBe` exchFromListUpper 5 es
+
diff --git a/test/ELynx/Import/MarkovProcess/EDMModelPhylobayesSpec.hs b/test/ELynx/Import/MarkovProcess/EDMModelPhylobayesSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/ELynx/Import/MarkovProcess/EDMModelPhylobayesSpec.hs
@@ -0,0 +1,135 @@
+{- |
+Module      :  ELynx.Import.MarkovProcess.EDMModelPhylobayesSpec
+Copyright   :  (c) Dominik Schrempf 2020
+License     :  GPL-3.0-or-later
+
+Maintainer  :  dominik.schrempf@gmail.com
+Stability   :  unstable
+Portability :  portable
+
+Creation date: Tue Jan 29 12:26:49 2019.
+
+-}
+
+module ELynx.Import.MarkovProcess.EDMModelPhylobayesSpec
+  ( spec
+  )
+where
+
+import           Numeric.LinearAlgebra          ( fromList )
+import           Test.Hspec
+
+import           ELynx.Tools
+
+import           ELynx.Import.MarkovProcess.EDMModelPhylobayes
+
+componentsFilePhylobayes :: FilePath
+componentsFilePhylobayes = "data/EDMDistsPhylobayes.txt"
+
+testComponents :: [EDMComponent]
+testComponents =
+  [ ( 0.3690726059430788
+    , fromList
+      [ 0.0746116859730418
+      , 0.0069967050701822
+      , 0.0792378063875672
+      , 0.1103113280153337
+      , 0.0084753541579630
+      , 0.0420976864270153
+      , 0.0359995156499732
+      , 0.0176053658394712
+      , 0.1140305648643406
+      , 0.0306656386818212
+      , 0.0143923751236750
+      , 0.0805907035564168
+      , 0.0136556223619922
+      , 0.0854829959418090
+      , 0.0907856579607629
+      , 0.0955855590305961
+      , 0.0585231905811694
+      , 0.0276404860443685
+      , 0.0024024774767569
+      , 0.0109092808557433
+      ]
+    )
+  , ( 0.28019163862430846
+    , fromList
+      [ 0.0379912838025543
+      , 0.0085917039746034
+      , 0.0016977963056655
+      , 0.0029780993213938
+      , 0.0369086689176780
+      , 0.0051768704164023
+      , 0.0027496797757250
+      , 0.2650202435999584
+      , 0.0035114356263963
+      , 0.2705514660371282
+      , 0.0634852940497682
+      , 0.0036512748214048
+      , 0.0030666766077233
+      , 0.0046946399741140
+      , 0.0039700770877914
+      , 0.0137110414055372
+      , 0.0286159990065166
+      , 0.2351259204392804
+      , 0.0018121721806795
+      , 0.0066896566496796
+      ]
+    )
+  , ( 0.23699880225859807
+    , fromList
+      [ 0.2699288544670601
+      , 0.0262695884363299
+      , 0.0119030286238640
+      , 0.0143694121662917
+      , 0.0113341089668980
+      , 0.1028437949687162
+      , 0.0097376980401260
+      , 0.0250662077996463
+      , 0.0137176088824149
+      , 0.0302792626622677
+      , 0.0151697996735645
+      , 0.0255041240872322
+      , 0.0194279535358810
+      , 0.0155053062932145
+      , 0.0146597721555602
+      , 0.2261838872893110
+      , 0.1040919090386891
+      , 0.0534187313840882
+      , 0.0024899475832214
+      , 0.0080990039456234
+      ]
+    )
+  , ( 0.11373695317401472
+    , fromList
+      [ 0.0325183213724537
+      , 0.0153142424565790
+      , 0.0072297704620506
+      , 0.0101526783552517
+      , 0.2682049848838039
+      , 0.0107298905683658
+      , 0.0420960604309369
+      , 0.0414751553493385
+      , 0.0131985876449809
+      , 0.1152120909184748
+      , 0.0300072241461393
+      , 0.0173787316286536
+      , 0.0062421326435569
+      , 0.0173124967325860
+      , 0.0181776303531701
+      , 0.0328778350287987
+      , 0.0250382111285986
+      , 0.0437257936268565
+      , 0.0258103804738129
+      , 0.2272977817955918
+      ]
+    )
+  ]
+
+spec :: Spec
+spec =
+  describe "phylobayes"
+    $ it "parses a text file with stationary distributions in phylobayes format"
+    $ do
+        cs <- parseFileWith phylobayes componentsFilePhylobayes
+        cs `shouldBe` testComponents
diff --git a/test/ELynx/Import/MarkovProcess/SiteprofilesPhylobayesSpec.hs b/test/ELynx/Import/MarkovProcess/SiteprofilesPhylobayesSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/ELynx/Import/MarkovProcess/SiteprofilesPhylobayesSpec.hs
@@ -0,0 +1,68 @@
+{- |
+Module      :  ELynx.Import.MarkovProcess.SiteprofilesPhylobayesSpec
+Copyright   :  (c) Dominik Schrempf 2020
+License     :  GPL-3.0-or-later
+
+Maintainer  :  dominik.schrempf@gmail.com
+Stability   :  unstable
+Portability :  portable
+
+Creation date: Wed Sep 18 09:51:35 2019.
+
+-}
+
+module ELynx.Import.MarkovProcess.SiteprofilesPhylobayesSpec
+  ( spec
+  )
+where
+
+import qualified Data.Vector.Storable          as V
+import           Test.Hspec
+
+import           ELynx.Tools
+
+import           ELynx.Import.MarkovProcess.EDMModelPhylobayes
+                                                ( EDMComponent )
+import           ELynx.Import.MarkovProcess.SiteprofilesPhylobayes
+
+fn :: FilePath
+fn = "data/HSSPMany.siteprofiles"
+
+getProfiles :: IO [EDMComponent]
+getProfiles = parseFileWith siteprofiles fn
+
+firstProfile :: V.Vector Double
+firstProfile = V.fromList
+  [ 0.0267009
+  , 0.013874
+  , 0.022432
+  , 0.0440502
+  , 0.0485174
+  , 0.0407515
+  , 0.0170806
+  , 0.348043
+  , 0.0371379
+  , 0.0715536
+  , 0.0454168
+  , 0.0342213
+  , 0.0146872
+  , 0.0239681
+  , 0.0768379
+  , 0.0210387
+  , 0.0123336
+  , 0.0512678
+  , 0.0149093
+  , 0.0351776
+  ]
+
+spec :: Spec
+spec =
+  describe "import phylobayes siteprofiles"
+    $ it "parses a text file with siteprofiles in phylobayes format"
+    $ do
+        profiles <- getProfiles
+        length profiles `shouldBe` 701
+        map fst profiles `shouldBe` replicate 701 1.0
+        map (V.sum . snd) profiles
+          `shouldSatisfy` nearlyEqListWith 1e-5 (replicate 701 1.0)
+        snd (head profiles) `shouldBe` firstProfile
diff --git a/test/ELynx/Simulate/MarkovProcessAlongTreeSpec.hs b/test/ELynx/Simulate/MarkovProcessAlongTreeSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/ELynx/Simulate/MarkovProcessAlongTreeSpec.hs
@@ -0,0 +1,66 @@
+{- |
+Module      :  ELynx.Simulate.MarkovProcessAlongTreeSpec
+Copyright   :  (c) Dominik Schrempf 2020
+License     :  GPL-3.0-or-later
+
+Maintainer  :  dominik.schrempf@gmail.com
+Stability   :  unstable
+Portability :  portable
+
+Creation date: Thu Jan 24 15:25:49 2019.
+
+-}
+
+module ELynx.Simulate.MarkovProcessAlongTreeSpec
+  ( spec
+  )
+where
+
+import           Data.Tree
+import           System.Random.MWC
+import           Test.Hspec
+
+import           ELynx.Data.MarkovProcess.Nucleotide
+import qualified ELynx.Data.MarkovProcess.SubstitutionModel
+                                               as S
+import           ELynx.Data.Tree
+import           ELynx.Simulate.MarkovProcess
+import           ELynx.Simulate.MarkovProcessAlongTree
+
+-- sampleNewickText :: T.Text
+-- sampleNewickText = T.pack "(Aeropyrum0:0.5478645225,(((((((((Arabidopsi:0.0701001024,Oryza_sati:0.0765988261):0.0309636193,Gymnosperm:0.0520325624):0.0338982245,Physcomitr:0.0768008916):0.0895714685,(Chlamydomo:0.1136227755,Dunaliella:0.1406347323):0.1117340620):0.0818876186,Rhodophyta:0.3405656487):0.0363527066,((((((Babesia_bo:0.1646969208,Theileria0:0.1519889486):0.1908081096,Plasmodium:0.3250696762):0.0637865908,(Toxoplasma:0.1153570425,Eimeria000:0.1671916078):0.0980136930):0.0518956330,Cryptospor:0.3175062809):0.1607708388,Ciliophora:0.5687502950):0.0624078848,(Phytophtho:0.2016424948,((Thalassios:0.1202730781,Phaeodacty:0.1290341329):0.1772775509,Phaeophyce:0.1989260715):0.0312359673):0.1154768302):0.0311952864):0.0149160316,(((((((((Candida_al:0.1027755272,Saccharomy:0.1190206560):0.1333487870,Neurospora:0.1977309079):0.0522926266,Schizosacc:0.2019603227):0.0567441011,(Cryptococc:0.1948614959,Ustilago_m:0.1564451295):0.0775729694):0.0323959951,Glomus_int:0.1573670796):0.0194701292,Chytridiom:0.2228415254):0.0384370601,Encephalit:1.4622174644):0.0416231688,(((Drosophila:0.2160627753,(Mammalians:0.1080484094,Tunicates0:0.1739253014):0.0289624371):0.0346633757,Hydrozoa00:0.2058137032):0.0480963050,Monosiga_b:0.3020637584):0.0654894239):0.0380915725,(Dictyostel:0.3453588998,Mastigamoe:0.3844779231):0.0478795653):0.0129578395):1.7592083381,((Archaeoglo:0.5402784445,Methanococ:0.4088567459):0.0993669265,Pyrococcus:0.4058713829):0.1734405968):0.2193511807,Pyrobaculu:0.7507718047):0.1646616482,Sulfolobus:0.5404967897);"
+
+testTree :: Tree (PhyloLabel Int)
+testTree = Node
+  (PhyloLabel 0 Nothing (Just 0.0))
+  [ Node (PhyloLabel 1 Nothing (Just 1.0)) []
+  , Node (PhyloLabel 2 Nothing (Just 1.0)) []
+  ]
+
+-- testStateTree :: Tree State
+-- testStateTree = Node 0 [Node 3 [], Node 2 []]
+
+nullTree :: Tree (PhyloLabel Int)
+nullTree = Node (PhyloLabel 0 Nothing (Just 0.0)) []
+
+nullStateTree :: Tree State
+nullStateTree = fmap (const 0) nullTree
+
+-- uniformStationaryDistribution :: Int -> Vector R
+-- uniformStationaryDistribution n = fromList $ replicate n (1.0 / fromIntegral n)
+
+spec :: Spec
+spec = describe "simulateNSitesAlongTree" $ do
+  it "simulates one site along an easy tree" $ do
+    gen <- create
+    tr  <- simulate 1 d e nullTree gen
+    fmap head tr `shouldBe` nullStateTree
+
+  it "simulates some sites along a harder tree" $ do
+    gen <- create
+    tr  <- simulate 10 d e testTree gen
+    (length . rootLabel $ tr) `shouldBe` 10
+ where
+  d = S.stationaryDistribution jc
+  e = S.exchangeabilityMatrix jc
+
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,1 @@
+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
