diff --git a/LICENSE b/LICENSE index f288702d..261eeb9e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,674 +1,201 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Project.toml b/Project.toml index 6f5c307b..7e6c96a3 100644 --- a/Project.toml +++ b/Project.toml @@ -1,48 +1,24 @@ name = "SpinGlassPEPS" uuid = "2c514f87-1261-494e-8566-326879aaf4fe" -authors = ["Łukasz Pawela ", "Krzysztof Domino "] -version = "0.0.1" +version = "0.2.0" [deps] -CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" -DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -LRUCache = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637" -LightGraphs = "093fc24a-ae57-5d10-9952-331d41423f4d" -LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" -LowRankApprox = "898213cb-b102-5a47-900c-97e73b919f73" -Memoize = "c03570c3-d221-55d1-a50c-7939bbd78826" -MetaGraphs = "626554b9-1ddb-594c-aa3c-2596fe9399a5" -Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +Reexport = "189a3867-3050-52da-a836-e630ba90ab69" Requires = "ae029012-a4dd-5104-9daa-d747884805df" -Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -TensorCast = "02d47bb6-7ce6-556a-be16-bb1710789e2b" -TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2" +SpinGlassEngine = "0563570f-ea1b-4080-8a64-041ac6565a4e" +SpinGlassNetworks = "b7f6bd3e-55dc-4da6-96a9-ef9dbec6ac19" +SpinGlassTensors = "7584fc6a-5a23-4eeb-8277-827aab0146ea" [compat] -CSV = "0.8" CUDA = "2.3" -DocStringExtensions = "0.8" -LRUCache = "1.2" -LightGraphs = "1.3" -LowRankApprox = "0.4" -Memoize = "0.4" -MetaGraphs = "0.6" -Requires = "1.1" -StatsBase = "0.33" -TensorCast = "0.3" -TensorOperations = "3.0.1" +SpinGlassEngine = "0.1" +SpinGlassNetworks = "0.1" +SpinGlassTensors = "0.1" julia = "1.5" [extras] -GraphPlot = "a2cc645c-3eea-5389-862e-a155d0052231" -Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" -NPZ = "15e1cf62-19b3-5cfa-8e77-841668bca605" -Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["GraphPlot", "Logging", "NPZ", "Random", "Statistics", "Test"] +test = ["Test"] diff --git a/lattice_3.txt b/lattice_3.txt deleted file mode 100644 index 52761369..00000000 --- a/lattice_3.txt +++ /dev/null @@ -1,22 +0,0 @@ -i j v -1 2 0.1 -2 3 0.3 -4 5 0.7 -5 6 0.6 -7 8 0.5 -8 9 0.5 -1 4 0.7 -4 7 0.7 -2 5 0.2 -5 8 0.7 -3 6 0.3 -6 9 0.4 -1 1 0.1 -2 2 0.2 -3 3 0.3 -4 4 0.4 -5 5 0.5 -6 6 0.6 -7 7 0.7 -8 8 0.8 -9 9 0.9 diff --git a/src/MPS_search.jl b/src/MPS_search.jl deleted file mode 100644 index 0bcf5931..00000000 --- a/src/MPS_search.jl +++ /dev/null @@ -1,288 +0,0 @@ -export MPSControl -export solve, solve_new -export MPS2 - -struct MPSControl - max_bond::Int - var_ϵ::Number - max_sweeps::Int - β::Number - dβ::Number -end - -_make_left_env(ψ::AbstractMPS, k::Int) = ones(eltype(ψ), 1, 1, k) -_make_left_env_new(ψ::AbstractMPS, k::Int) = ones(eltype(ψ), 1, k) -_make_LL(ψ::AbstractMPS, b::Int, k::Int, d::Int) = zeros(eltype(ψ), b, b, k, d) -_make_LL_new(ψ::AbstractMPS, b::Int, k::Int, d::Int) = zeros(eltype(ψ), b, k, d) - -# ρ needs to be ∈ the right canonical form -# function solve(ψ::AbstractMPS, keep::Int) -# @assert keep > 0 "Number of states has to be > 0" -# T = eltype(ψ) - -# keep_extra = keep -# pCut = prob = 0. -# k = 1 - -# if keep < prod(rank(ψ)) -# keep_extra += 1 -# end - -# states = fill([], 1, k) -# left_env = _make_left_env(ψ, k) - -# for (i, M) ∈ enumerate(ψ) -# _, d, b = size(M) - -# pdo = zeros(T, k, d) -# LL = _make_LL(ψ, b, k, d) -# config = zeros(Int, i, k, d) - -# for j ∈ 1:k -# L = left_env[:, :, j] - -# for σ ∈ local_basis(d) -# m = idx(σ) -# LL[:, :, j, m] = M[:, m, :]' * (L * M[:, m, :]) -# pdo[j, m] = tr(LL[:, :, j, m]) -# config[:, j, m] = vcat(states[:, j]..., σ) -# end -# end - -# perm = collect(1: k * d) -# k = min(k * d, keep_extra) - -# if k >= keep_extra -# partialsortperm!(perm, vec(pdo), 1:k, rev=true) -# prob = vec(pdo)[perm] -# pCut < last(prob) ? pCut = last(prob) : () -# end - -# @cast A[α, β, (l, d)] |= LL[α, β, l, d] -# left_env = A[:, :, perm] - -# @cast B[α, (l, d)] |= config[α, l, d] -# states = B[:, perm] -# end -# states[:, 1:keep], prob[1:keep], pCut -# end - - -# ψ needs to be ∈ the right canonical form -function solve(ψ::AbstractMPS, keep::Int) - @assert keep > 0 "Number of states has to be > 0" - T = eltype(ψ) - - keep_extra = keep - lpCut = -1000 # do not like this! - k = 1 - - # this is not elegant - if keep < prod(rank(ψ)) - keep_extra += 1 - end - - lprob = zeros(T, k) - states = fill([], 1, k) - left_env = _make_left_env_new(ψ, k) - - for (i, M) ∈ enumerate(ψ) - _, d, b = size(M) - - pdo = ones(T, k, d) - lpdo = zeros(T, k, d) - LL = _make_LL_new(ψ, b, k, d) - config = zeros(Int, i, k, d) - - for j ∈ 1:k - L = left_env[:, j] - - for σ ∈ local_basis(d) - m = idx(σ) - LL[:, j, m] = L' * M[:, m, :] - pdo[j, m] = dot(LL[:, j, m], LL[:, j, m]) - config[:, j, m] = vcat(states[:, j]..., σ) - LL[:, j, m] = LL[:, j, m] / sqrt(pdo[j, m]) - end - pdo[j, :] = pdo[j, :] / sum(pdo[j, :]) - lpdo[j, :] = log.(pdo[j, :]) .+ lprob[j] - end - - perm = collect(1 : k * d) - k = k * d - - if k > keep_extra - k = keep_extra - partialsortperm!(perm, vec(lpdo), 1:k, rev=true) - lprob = vec(lpdo)[perm] - lpCut < last(lprob) ? lpCut = last(lprob) : () - end - - lprob = vec(lpdo)[perm] - @cast A[α, (l, d)] |= LL[α, l, d] - left_env = A[:, perm] - @cast B[β, (l, d)] |= config[β, l, d] - states = B[:, perm] - end - states', lprob, lpCut -end - -function _apply_bias!(ψ::AbstractMPS, ig::MetaGraph, dβ::Number, i::Int) - M = ψ[i] - d = size(M, 2) - - h = get_prop(ig, i, :h) - - v = exp.(-0.5 * dβ * h * local_basis(ψ, i)) - @cast M[x, σ, y] = M[x, σ, y] * v[σ] - ψ[i] = M -end - -function _apply_exponent!(ψ::AbstractMPS, ig::MetaGraph, dβ::Number, i::Int, j::Int, last::Int) - M = ψ[j] - D = typeof(M).name.wrapper(I(physical_dim(ψ, i))) - - J = get_prop(ig, i, j, :J) - C = exp.(-0.5 * dβ * J * local_basis(ψ, i) * local_basis(ψ, j)') - - if j == last - @cast M̃[(x, a), σ, b] := C[x, σ] * M[a, σ, b] - else - @cast M̃[(x, a), σ, (y, b)] := C[x, σ] * D[x, y] * M[a, σ, b] - end - - ψ[j] = M̃ -end - -function _apply_projector!(ψ::AbstractMPS, i::Int) - M = ψ[i] - D = typeof(M).name.wrapper(I(physical_dim(ψ, i))) - - @cast M̃[a, σ, (y, b)] := D[σ, y] * M[a, σ, b] - ψ[i] = M̃ -end - -function _apply_nothing!(ψ::AbstractMPS, l::Int, i::Int) - M = ψ[l] - D = typeof(M).name.wrapper(I(physical_dim(ψ, i))) - - @cast M̃[(x, a), σ, (y, b)] := D[x, y] * M[a, σ, b] - ψ[l] = M̃ -end - - -function multiply_purifications(χ::T, ϕ::T, L::Int) where {T <: AbstractMPS} - S = promote_type(eltype(χ), eltype(ϕ)) - ψ = T.name.wrapper(S, L) - - for i ∈ 1:L - A1 = χ[i] - A2 = ϕ[i] - - @cast B[(l, x), σ, (r, y)] := A1[l, σ, r] * A2[x, σ, y] - ψ[i] = B - end - ψ -end - -_holes(l::Int, nbrs::Vector) = setdiff(l+1 : last(nbrs), nbrs) - -function _apply_layer_of_gates(ig::MetaGraph, ρ::AbstractMPS, control::MPSControl, dβ::Number) - L = nv(ig) - Dcut = control.max_bond - tol = control.var_ϵ - max_sweeps = control.max_sweeps - for i ∈ 1:L - _apply_bias!(ρ, ig, dβ, i) - is_right = false - nbrs = unique_neighbors(ig, i) - if !isempty(nbrs) - _apply_projector!(ρ, i) - - for j ∈ nbrs - _apply_exponent!(ρ, ig, dβ, i, j, last(nbrs)) - end - - for l ∈ _holes(i, nbrs) - _apply_nothing!(ρ, l, i) - end - end - - if bond_dimension(ρ) > Dcut - @info "Compresing MPS" bond_dimension(ρ), Dcut - ρ = compress(ρ, Dcut, tol, max_sweeps) - is_right = true - end - - end - if !is_right - canonise!(ρ, :right) - is_right = true - end - ρ -end - -function MPS(ig::MetaGraph, control::MPSControl) - - Dcut = control.max_bond - tol = control.var_ϵ - max_sweeps = control.max_sweeps - schedule = control.β - @info "Set control parameters for MPS" Dcut tol max_sweeps - rank = get_prop(ig, :rank) - - @info "Preparing Hadamard state as MPS" - ρ = HadamardMPS(rank) - is_right = true - @info "Sweeping through β and σ" schedule - for dβ ∈ schedule - ρ = _apply_layer_of_gates(ig, ρ, control, dβ) - end - ρ -end - -function MPS(ig::MetaGraph, control::MPSControl, type::Symbol) - L = nv(ig) - Dcut = control.max_bond - tol = control.var_ϵ - max_sweeps = control.max_sweeps - dβ = control.dβ - β = control.β - @info "Set control parameters for MPS" Dcut tol max_sweeps - rank = get_prop(ig, :rank) - - @info "Preparing Hadamard state as MPS" - ρ = HadamardMPS(rank) - is_right = true - @info "Sweeping through β and σ" dβ - - if type == :log - k = ceil(log2(β/dβ)) - dβmax = β/(2^k) - ρ = _apply_layer_of_gates(ig, ρ, control, dβmax) - for j ∈ 1:k - ρ = multiply_purifications(ρ, ρ, L) - if bond_dimension(ρ) > Dcut - @info "Compresing MPS" bond_dimension(ρ), Dcut - ρ = compress(ρ, Dcut, tol, max_sweeps) - is_right = true - end - end - ρ - elseif type == :lin - k = β/dβ - dβmax = β/k - ρ = _apply_layer_of_gates(ig, ρ, control, dβmax) - ρ0 = copy(ρ) - for j ∈ 1:k - ρ = multiply_purifications(ρ, ρ0, L) - if bond_dimension(ρ) > Dcut - @info "Compresing MPS" bond_dimension(ρ), Dcut - ρ = compress(ρ, Dcut, tol, max_sweeps) - is_right = true - end - end - end - ρ - -end diff --git a/src/PEPS.jl b/src/PEPS.jl deleted file mode 100644 index 86ad0cb0..00000000 --- a/src/PEPS.jl +++ /dev/null @@ -1,298 +0,0 @@ -export PEPSNetwork, contract_network -export MPO, MPS, generate_boundary - -const DEFAULT_CONTROL_PARAMS = Dict( - "bond_dim" => typemax(Int), - "var_tol" => 1E-8, - "sweeps" => 4., - "β" => 1. -) - -struct PEPSNetwork <: AbstractGibbsNetwork - size::NTuple{2, Int} - map::Dict - fg::MetaDiGraph - nbrs::Dict - origin::Symbol - i_max::Int - j_max::Int - β::Number # TODO: get rid of this - args::Dict{String, Number} - - function PEPSNetwork( - m::Int, - n::Int, - fg::MetaDiGraph, - β::Number, - origin::Symbol=:NW, - args_override::Dict{String, T}=Dict{String, Number}() # TODO: change String to Symbol - ) where T <: Number - map, i_max, j_max = peps_indices(m, n, origin) - - # v => (l, u, r, d) - nbrs = Dict( - map[i, j] => (map[i, j-1], map[i-1, j], map[i, j+1], map[i+1, j]) - for i ∈ 1:i_max, j ∈ 1:j_max - ) - - args = merge(DEFAULT_CONTROL_PARAMS, args_override) - pn = new((m, n), map, fg, nbrs, origin, i_max, j_max, β, args) - end -end - -function _get_projector(fg::MetaDiGraph, v::Int, w::Int) - if has_edge(fg, w, v) - get_prop(fg, w, v, :pr)' - elseif has_edge(fg, v, w) - get_prop(fg, v, w, :pl) - else - loc_dim = length(get_prop(fg, v, :loc_en)) - ones(loc_dim, 1) - end -end - -@memoize function generate_tensor(network::PEPSNetwork, v::Int) - # TODO: does this require full network, or can we pass only fg? - loc_exp = exp.(-network.β .* get_prop(network.fg, v, :loc_en)) - - dim = zeros(Int, length(network.nbrs[v])) - @cast A[_, i] := loc_exp[i] - - for (j, w) ∈ enumerate(network.nbrs[v]) - pv = _get_projector(network.fg, v, w) - @cast A[(c, γ), σ] |= A[c, σ] * pv[σ, γ] - dim[j] = size(pv, 2) - end - reshape(A, dim..., :) -end - -@memoize function generate_tensor(network::PEPSNetwork, v::Int, w::Int) - fg = network.fg - if has_edge(fg, w, v) - en = get_prop(fg, w, v, :en)' - elseif has_edge(fg, v, w) - en = get_prop(fg, v, w, :en) - else - en = zeros(1, 1) - end - exp.(-network.β .* (en .- minimum(en))) -end - -function peps_tensor(::Type{T}, peps::PEPSNetwork, i::Int, j::Int) where {T <: Number} - # generate tensors from projectors - A = generate_tensor(peps, peps.map[i, j]) - - # include energy - h = generate_tensor(peps, peps.map[i, j-1], peps.map[i, j]) - v = generate_tensor(peps, peps.map[i-1, j], peps.map[i, j]) - @tensor B[l, u, r, d, σ] := h[l, l̃] * v[u, ũ] * A[l̃, ũ, r, d, σ] - B -end -peps_tensor(peps::PEPSNetwork, i::Int, j::Int) = peps_tensor(Float64, peps, i, j) - -function PEPSRow(::Type{T}, peps::PEPSNetwork, i::Int) where {T <: Number} - ψ = PEPSRow(T, peps.j_max) - for j ∈ 1:peps.j_max - ψ[j] = peps_tensor(T, peps, i, j) - end - ψ -end -PEPSRow(peps::PEPSNetwork, i::Int) = PEPSRow(Float64, peps, i) - -function MPO(::Type{T}, - peps::PEPSNetwork, - i::Int, - config::Dict{Int, Int} = Dict{Int, Int}() - ) where {T <: Number} - - W = MPO(T, peps.j_max) - R = PEPSRow(T, peps, i) - - for (j, A) ∈ enumerate(R) - v = get(config, j + peps.j_max * (i - 1), nothing) - if v !== nothing - @cast B[l, u, r, d] |= A[l, u, r, d, $(v)] - else - @reduce B[l, u, r, d] |= sum(σ) A[l, u, r, d, σ] - end - W[j] = B - end - W -end - -MPO(peps::PEPSNetwork, - i::Int, - config::Dict{Int, Int} = Dict{Int, Int}() - ) = MPO(Float64, peps, i, config) - -function compress(ψ::AbstractMPS, peps::PEPSNetwork) - Dcut = peps.args["bond_dim"] - if bond_dimension(ψ) < Dcut return ψ end - compress(ψ, Dcut, peps.args["var_tol"], peps.args["sweeps"]) -end - -@memoize function MPS( - peps::PEPSNetwork, - i::Int, - cfg::Dict{Int, Int} = Dict{Int, Int}(), - ) - if i > peps.i_max return IdentityMPS() end - W = MPO(peps, i, cfg) - ψ = MPS(peps, i+1, cfg) - compress(W * ψ, peps) -end - -function contract_network( - peps::PEPSNetwork, - config::Dict{Int, Int} = Dict{Int, Int}(), -) - ψ = MPS(peps, 1, config) - prod(dropindices(ψ))[] -end - -@inline function get_coordinates(peps::PEPSNetwork, k::Int) - ceil(Int, k / peps.j_max), (k - 1) % peps.j_max + 1 -end - -function generate_boundary(fg::MetaDiGraph, v::Int, w::Int, state::Int) - if v ∉ vertices(fg) return 1 end - loc_dim = length(get_prop(fg, v, :loc_en)) - pv = _get_projector(fg, v, w) - findfirst(x -> x > 0, pv[state, :]) -end - -function generate_boundary(peps::PEPSNetwork, v::Vector{Int}, w::NTuple{2, Int}) - i, j = w - ∂v = zeros(Int, peps.j_max + 1) - - # on the left below - for k ∈ 1:j-1 - ∂v[k] = generate_boundary( - peps.fg, - peps.map[i, k], - peps.map[i+1, k], - _get_local_state(peps, v, (i, k)) - ) - end - - # on the left at the current row - ∂v[j] = generate_boundary( - peps.fg, - peps.map[i, j-1], - peps.map[i, j], - _get_local_state(peps, v, (i, j-1)) - ) - - # on the right above - for k ∈ j:peps.j_max - ∂v[k+1] = generate_boundary( - peps.fg, - peps.map[i-1, k], - peps.map[i, k], - _get_local_state(peps, v, (i-1, k)) - ) - end - ∂v -end - -function _get_local_state(peps::PEPSNetwork, σ::Vector{Int}, w::NTuple{2, Int}) - k = w[2] + peps.j_max * (w[1] - 1) - 0 < k <= length(σ) ? σ[k] : 1 -end - -function _normalize_probability(prob::Vector{T}) where {T <: Number} - # exceptions (negative pdo, etc) - # will be added here later - prob / sum(prob) -end - -function conditional_probability( - peps::PEPSNetwork, - v::Vector{Int}, - ) - i, j = get_coordinates(peps, length(v)+1) - ∂v = generate_boundary(peps, v, (i, j)) - - W = MPO(peps, i) - ψ = MPS(peps, i+1) - - L = left_env(ψ, ∂v[1:j-1]) - R = right_env(ψ, W, ∂v[j+2:peps.j_max+1]) - A = peps_tensor(peps, i, j) - - l, u = ∂v[j:j+1] - M = ψ[j] - Ã = A[l, u, :, :, :] - @tensor prob[σ] := L[x] * M[x, d, y] * - Ã[r, d, σ] * R[y, r] order = (x, d, r, y) - _normalize_probability(prob) -end - -function bond_energy(fg::MetaDiGraph, u::Int, v::Int, σ::Int) - if has_edge(fg, u, v) - pu, en, pv = get_prop.(Ref(fg), u, v, (:pl, :en, :pr)) - energies = (pu * (en * pv[:, σ:σ]))' - elseif has_edge(fg, v, u) - pv, en, pu = get_prop.(Ref(fg), v, u, (:pl, :en, :pr)) - energies = (pv[σ:σ, :] * en) * pu - else - energies = zeros(get_prop(fg, u, :loc_dim)) - end - vec(energies) -end - -function update_energy( - network::AbstractGibbsNetwork, - σ::Vector{Int}, - ) - i, j = get_coordinates(network, length(σ)+1) - - σkj = _get_local_state(network, σ, (i-1, j)) - σil = _get_local_state(network, σ, (i, j-1)) - - bond_energy(network.fg, network.map[i, j], network.map[i, j-1], σil) + - bond_energy(network.fg, network.map[i, j], network.map[i-1, j], σkj) + - get_prop(network.fg, network.map[i, j], :loc_en) -end - -#TODO: translate this into rotations and reflections -function peps_indices(m::Int, n::Int, origin::Symbol=:NW) - @assert origin ∈ (:NW, :WN, :NE, :EN, :SE, :ES, :SW, :WS) - - ind = Dict() - if origin == :NW - for i ∈ 1:m, j ∈ 1:n push!(ind, (i, j) => (i - 1) * n + j) end - elseif origin == :WN - for i ∈ 1:n, j ∈ 1:m push!(ind, (i, j) => (j - 1) * n + i) end - elseif origin == :NE - for i ∈ 1:m, j ∈ 1:n push!(ind, (i, j) => (i - 1) * n + (n + 1 - j)) end - elseif origin == :EN - for i ∈ 1:n, j ∈ 1:m push!(ind, (i, j) => (j - 1) * n + (n + 1 - i)) end - elseif origin == :SE - for i ∈ 1:m, j ∈ 1:n push!(ind, (i, j) => (m - i) * n + (n + 1 - j)) end - elseif origin == :ES - for i ∈ 1:n, j ∈ 1:m push!(ind, (i, j) => (m - j) * n + (n + 1 - i)) end - elseif origin == :SW - for i ∈ 1:m, j ∈ 1:n push!(ind, (i, j) => (m - i) * n + j) end - elseif origin == :WS - for i ∈ 1:n, j ∈ 1:m push!(ind, (i, j) => (m - j) * n + i) end - end - - if origin ∈ (:NW, :NE, :SE, :SW) - i_max, j_max = m, n - else - i_max, j_max = n, m - end - - for i ∈ 0:i_max+1 - push!(ind, (i, 0) => 0) - push!(ind, (i, j_max + 1) => 0) - end - - for j ∈ 0:j_max+1 - push!(ind, (0, j) => 0) - push!(ind, (i_max + 1, j) => 0) - end - - ind, i_max, j_max -end diff --git a/src/SpinGlassPEPS.jl b/src/SpinGlassPEPS.jl index f2cfbde2..9bf20fc0 100644 --- a/src/SpinGlassPEPS.jl +++ b/src/SpinGlassPEPS.jl @@ -1,34 +1,12 @@ module SpinGlassPEPS - using LinearAlgebra - using Requires - using TensorOperations, TensorCast - using LowRankApprox - using LightGraphs - using MetaGraphs - using CSV - using Logging - using StatsBase - using Memoize, LRUCache - - using DocStringExtensions - const product = Iterators.product - include("base.jl") - include("utils.jl") - include("compressions.jl") - include("identities.jl") - include("contractions.jl") - include("lattice.jl") - include("ising.jl") - include("exact.jl") - include("factor.jl") - include("search.jl") - include("PEPS.jl") - include("MPS_search.jl") + using Reexport + @reexport using SpinGlassTensors, SpinGlassNetworks, SpinGlassEngine + using Requires function __init__() @require CUDA="052768ef-5323-5732-b1bb-66c8b64840ba" begin - if CUDA.functional() && CUDA.has_cutensor() + if CUDA.functional() && CUDA.has_cutensor() && false const CuArray = CUDA.CuArray const CuVector = CUDA.CuVector const CuMatrix = CUDA.CuMatrix diff --git a/src/base.jl b/src/base.jl deleted file mode 100644 index 06c05295..00000000 --- a/src/base.jl +++ /dev/null @@ -1,147 +0,0 @@ -export bond_dimension, is_left_normalized, is_right_normalized -export verify_bonds, verify_physical_dims, tensor, rank, physical_dim -export State, dropindices - -const State = Union{Vector, NTuple} - -abstract type AbstractTensorNetwork{T} end - -for (T, N) ∈ ((:PEPSRow, 5), (:MPO, 4), (:MPS, 3)) - AT = Symbol(:Abstract, T) - @eval begin - export $AT - export $T - - abstract type $AT{T} <: AbstractTensorNetwork{T} end - - struct $T{T <: Number} <: $AT{T} - tensors::Vector{Array{T, $N}} - end - - # consturctors - $T(::Type{T}, L::Int) where {T} = $T(Vector{Array{T, $N}}(undef, L)) - $T(L::Int) = $T(Float64, L) - - @inline Base.setindex!(a::$AT, A::AbstractArray{<:Number, $N}, i::Int) = a.tensors[i] = A - @inline bond_dimension(a::$AT) = maximum(size.(a.tensors, $N)) - Base.copy(a::$T) = $T(copy(a.tensors)) - - @inline Base.eltype(::$AT{T}) where {T} = T - end -end - -@inline Base.:(==)(a::AbstractTensorNetwork, b::AbstractTensorNetwork) = a.tensors == b.tensors -@inline Base.:(≈)(a::AbstractTensorNetwork, b::AbstractTensorNetwork) = a.tensors ≈ b.tensors - -@inline Base.getindex(a::AbstractTensorNetwork, i) = getindex(a.tensors, i) -@inline Base.iterate(a::AbstractTensorNetwork) = iterate(a.tensors) -@inline Base.iterate(a::AbstractTensorNetwork, state) = iterate(a.tensors, state) -@inline Base.lastindex(a::AbstractTensorNetwork) = lastindex(a.tensors) -@inline Base.length(a::AbstractTensorNetwork) = length(a.tensors) -@inline Base.size(a::AbstractTensorNetwork) = (length(a.tensors), ) -@inline Base.eachindex(a::AbstractTensorNetwork) = eachindex(a.tensors) - -@inline LinearAlgebra.rank(ψ::AbstractMPS) = Tuple(size(A, 2) for A ∈ ψ) -@inline physical_dim(ψ::AbstractMPS, i::Int) = size(ψ[i], 2) - -@inline MPS(A::AbstractArray) = MPS(A, :right) -@inline MPS(A::AbstractArray, s::Symbol, args...) = MPS(A, Val(s), typemax(Int), args...) -@inline MPS(A::AbstractArray, s::Symbol, Dcut::Int, args...) = MPS(A, Val(s), Dcut, args...) -@inline MPS(A::AbstractArray, ::Val{:right}, Dcut::Int, args...) = _left_sweep_SVD(MPS, A, Dcut, args...) -@inline MPS(A::AbstractArray, ::Val{:left}, Dcut::Int, args...) = _right_sweep_SVD(MPS, A, Dcut, args...) - -@inline dropindices(ψ::AbstractMPS, i::Int=2) = (dropdims(A, dims=i) for A ∈ ψ) - -function MPS(states::Vector{Vector{T}}) where {T <: Number} - state_arrays = [reshape(copy(v), (1, length(v), 1)) for v ∈ states] - MPS(state_arrays) -end - -function (::Type{T})(ψ::AbstractMPS) where {T <:AbstractMPO} - _verify_square(ψ) - T([ - @cast W[x, σ, y, η] |= A[x, (σ, η), y] (σ:isqrt(size(A, 2))) - for A in ψ - ]) -end - -function (::Type{T})(O::AbstractMPO) where {T <:AbstractMPS} - T([@cast A[x, (σ, η), y] := W[x, σ, y, η] for W in O]) -end - -function Base.randn(::Type{MPS{T}}, D::Int, rank::Union{Vector, NTuple}) where {T} - MPS([ - randn(T, 1, first(rank), D), - randn.(T, D, rank[begin+1:end-1], D)..., - rand(T, D, last(rank), 1) - ]) -end - -function Base.randn(::Type{MPS{T}}, L::Int, D::Int, d::Int) where {T} - MPS([ - randn(T, 1, d, D), (randn(T, D, d, D) for _ in 2:L-1)..., randn(T, D, d, 1) - ]) -end - -Base.randn(::Type{MPS}, args...) = randn(MPS{Float64}, args...) - -function Base.randn(::Type{MPO{T}}, L::Int, D::Int, d::Int) where {T} - MPO(randn(MPS{T}, L, D, d^2)) -end - -Base.randn(::Type{MPO}, args...) = randn(MPO{Float64}, args...) - -is_left_normalized(ψ::MPS) = all( - I(size(A, 3)) ≈ @tensor Id[x, y] := conj(A[α, σ, x]) * A[α, σ, y] order = (α, σ) for A ∈ ψ -) - -is_right_normalized(ϕ::MPS) = all( - I(size(B, 1)) ≈ @tensor Id[x, y] := B[x, σ, α] * conj(B[y, σ, α]) order = (α, σ) for B in ϕ -) - -function _verify_square(ψ::AbstractMPS) - dims = physical_dim.(Ref(ψ), eachindex(ψ)) - @assert isqrt.(dims) .^ 2 == dims "Incorrect MPS dimensions" -end - -function verify_physical_dims(ψ::AbstractMPS, dims::NTuple) - for i ∈ eachindex(ψ) - @assert physical_dim(ψ, i) == dims[i] "Incorrect physical dim at site $(i)." - end -end - -function verify_bonds(ψ::AbstractMPS) - L = length(ψ) - - @assert size(ψ[1], 1) == 1 "Incorrect size on the left boundary." - @assert size(ψ[end], 3) == 1 "Incorrect size on the right boundary." - - for i ∈ 1:L-1 - @assert size(ψ[i], 3) == size(ψ[i+1], 1) "Incorrect link between $i and $(i+1)." - end -end - -function Base.show(io::IO, ψ::AbstractTensorNetwork) - L = length(ψ) - dims = [size(A) for A ∈ ψ] - - println(io, "Matrix product state on $L sites:") - _show_sizes(io, dims) - println(io, " ") -end - - -function _show_sizes(io::IO, dims::Vector, sep::String=" x ", Lcut::Int=8) - L = length(dims) - if L > Lcut - for i ∈ 1:Lcut - print(io, " ", dims[i], sep) - end - print(io, " ... × ", dims[end]) - else - for i ∈ 1:(L-1) - print(io, dims[i], sep) - end - println(io, dims[end]) - end -end diff --git a/src/compressions.jl b/src/compressions.jl deleted file mode 100644 index a9dd774c..00000000 --- a/src/compressions.jl +++ /dev/null @@ -1,201 +0,0 @@ -export truncate!, canonise!, compress - -function compress(ψ::AbstractMPS, Dcut::Int, tol::Number=1E-8, max_sweeps::Int=4) - - # Initial guess - truncated ψ - ϕ = copy(ψ) - truncate!(ϕ, :right, Dcut) - - # Create environment - env = left_env(ϕ, ψ) - - # Variational compression - overlap = 0 - overlap_before = 1 - - @info "Compressing down to" Dcut - - for sweep ∈ 1:max_sweeps - _left_sweep_var!!(ϕ, env, ψ, Dcut) - overlap = _right_sweep_var!!(ϕ, env, ψ, Dcut) - - diff = abs(overlap_before - abs(overlap)) - @info "Convergence" diff - - if diff < tol - @info "Finished in $sweep sweeps of $(max_sweeps)." - return ϕ - else - overlap_before = overlap - end - end - ϕ -end - -function canonise!(ψ::AbstractMPS) - canonise!(ψ, :right) - canonise!(ψ, :left) -end - -canonise!(ψ::AbstractMPS, s::Symbol) = canonise!(ψ, Val(s)) -canonise!(ψ::AbstractMPS, ::Val{:right}) = _left_sweep_SVD!(ψ) -canonise!(ψ::AbstractMPS, ::Val{:left}) = _right_sweep_SVD!(ψ) - -truncate!(ψ::AbstractMPS, s::Symbol, Dcut::Int) = truncate!(ψ, Val(s), Dcut) -truncate!(ψ::AbstractMPS, ::Val{:right}, Dcut::Int) = _left_sweep_SVD!(ψ, Dcut) -truncate!(ψ::AbstractMPS, ::Val{:left}, Dcut::Int) = _right_sweep_SVD!(ψ, Dcut) - -function _right_sweep_SVD!(ψ::AbstractMPS, Dcut::Int=typemax(Int)) - Σ = V = ones(eltype(ψ), 1, 1) - - for i ∈ eachindex(ψ) - A = ψ[i] - C = (Diagonal(Σ) ./ Σ[1]) * V' - - # attach - @tensor M[x, σ, y] := C[x, α] * A[α, σ, y] - @cast M̃[(x, σ), y] |= M[x, σ, y] - - # decompose - U, Σ, V = svd(M̃, Dcut) - - # create new - d = physical_dim(ψ, i) - @cast A[x, σ, y] |= U[(x, σ), y] (σ:d) - ψ[i] = A - end - ψ[end] *= tr(V) -end - -function _left_sweep_SVD!(ψ::AbstractMPS, Dcut::Int=typemax(Int)) - Σ = U = ones(eltype(ψ), 1, 1) - - for i ∈ length(ψ):-1:1 - B = ψ[i] - C = U * (Diagonal(Σ) ./ Σ[1]) - - # attach - @tensor M[x, σ, y] := B[x, σ, α] * C[α, y] - @cast M̃[x, (σ, y)] |= M[x, σ, y] - - # decompose - U, Σ, V = svd(M̃, Dcut) - - # create new - d = physical_dim(ψ, i) - @cast B[x, σ, y] |= V'[x, (σ, y)] (σ:d) - ψ[i] = B - end - ψ[1] *= tr(U) -end - -function _left_sweep_var!!(ϕ::AbstractMPS, env::Vector{<:AbstractMatrix}, ψ::AbstractMPS, Dcut::Int) - S = eltype(ϕ) - - # overwrite the overlap - env[end] = ones(S, 1, 1) - - for i ∈ length(ψ):-1:1 - L = env[i] - R = env[i+1] - - # optimize site - M = ψ[i] - @tensor M̃[x, σ, y] := L[x, β] * M[β, σ, α] * R[α, y] order = (α, β) - - # right canonize it - @cast MM[x, (σ, y)] |= M̃[x, σ, y] - Q = rq(MM, Dcut) - - d = size(M, 2) - @cast B[x, σ, y] |= Q[x, (σ, y)] (σ:d) - - # update ϕ and right environment - ϕ[i] = B - A = ψ[i] - - @tensor RR[x, y] := A[x, σ, α] * R[α, β] * conj(B[y, σ, β]) order = (β, α, σ) - env[i] = RR - end -end - -function _right_sweep_var!!(ϕ::AbstractMPS, env::Vector{<:AbstractMatrix}, ψ::AbstractMPS, Dcut::Int) - S = eltype(ϕ) - - # overwrite the overlap - env[1] = ones(S, 1, 1) - - for i ∈ eachindex(ψ) - L = env[i] - R = env[i+1] - - # optimize site - M = ψ[i] - @tensor M̃[x, σ, y] := L[x, β] * M[β, σ, α] * R[α, y] order = (α, β) - - # left canonize it - @cast B[(x, σ), y] |= M̃[x, σ, y] - Q = qr(B, Dcut) - - d = size(ϕ[i], 2) - @cast A[x, σ, y] |= Q[(x, σ), y] (σ:d) - - # update ϕ and left environment - ϕ[i] = A - B = ψ[i] - - @tensor LL[x, y] := conj(A[β, σ, x]) * L[β, α] * B[α, σ, y] order = (α, β, σ) - env[i+1] = LL - end - real(env[end][1]) -end - - -function _right_sweep_SVD(::Type{T}, A::AbstractArray, Dcut::Int=typemax(Int), args...) where {T <: AbstractMPS} - rank = ndims(A) - ψ = T(eltype(A), rank) - - V = reshape(copy(conj(A)), (length(A), 1)) - - for i ∈ 1:rank - d = size(A, i) - - # reshape - VV = conj.(transpose(V)) - @cast M[(x, σ), y] |= VV[x, (σ, y)] (σ:d) - - # decompose - U, Σ, V = svd(M, Dcut, args...) - V *= Diagonal(Σ) - - # create MPS - @cast B[x, σ, y] |= U[(x, σ), y] (σ:d) - ψ[i] = B - end - ψ -end - - -function _left_sweep_SVD(::Type{T}, A::AbstractArray, Dcut::Int=typemax(Int), args...) where {T <: AbstractMPS} - rank = ndims(A) - ψ = T(eltype(A), rank) - - U = reshape(copy(A), (length(A), 1)) - - for i ∈ rank:-1:1 - d = size(A, i) - - # reshape - @cast M[x, (σ, y)] |= U[(x, σ), y] (σ:d) - - # decompose - U, Σ, V = svd(M, Dcut, args...) - U *= Diagonal(Σ) - - # create MPS - VV = conj.(transpose(V)) - @cast B[x, σ, y] |= VV[x, (σ, y)] (σ:d) - ψ[i] = B - end - ψ -end \ No newline at end of file diff --git a/src/contractions.jl b/src/contractions.jl deleted file mode 100644 index 8378f4da..00000000 --- a/src/contractions.jl +++ /dev/null @@ -1,184 +0,0 @@ -export left_env, right_env, dot! - -# --------------------------- Conventions ----------------------- -# -# MPS MPS* MPO left env right env -# 2 2 2 - 1 2 - -# 1 - A - 3 1 - B - 3 1 - W - 3 L R -# 4 - 2 1 - -# --------------------------------------------------------------- -# - -function LinearAlgebra.dot(ψ::AbstractMPS, state::Union{Vector, NTuple}) - C = I - - for (M, σ) ∈ zip(ψ, state) - i = idx(σ) - C = M[:, i, :]' * (C * M[:, i, :]) - end - tr(C) -end - -function LinearAlgebra.dot(ϕ::AbstractMPS, ψ::AbstractMPS) - T = promote_type(eltype(ψ), eltype(ϕ)) - C = ones(T, 1, 1) - - for i ∈ eachindex(ψ) - M = ψ[i] - M̃ = conj(ϕ[i]) - @tensor C[x, y] := M̃[β, σ, x] * C[β, α] * M[α, σ, y] order = (α, β, σ) - end - tr(C) -end - -function left_env(ϕ::AbstractMPS, ψ::AbstractMPS) - l = length(ψ) - T = promote_type(eltype(ψ), eltype(ϕ)) - S = typeof(similar(ψ[1], T, (1, 1))) - L = Vector{S}(undef, l+1) - L[1] = similar(ψ[1], T, (1, 1)) - L[1][1, 1] = one(T) - - for i ∈ 1:l - M = ψ[i] - M̃ = conj.(ϕ[i]) - - C = L[i] - @tensor C[x, y] := M̃[β, σ, x] * C[β, α] * M[α, σ, y] order = (α, β, σ) - L[i+1] = C - end - L -end - -@memoize function left_env(ϕ::AbstractMPS, σ::Vector{Int}) - l = length(σ) - if l == 0 - L = [1.] - else - m = σ[l] - L̃ = left_env(ϕ, σ[1:l-1]) - M = ϕ[l] - @reduce L[x] := sum(α) L̃[α] * M[α, $m, x] - end - L -end - -# NOT tested yet -function right_env(ϕ::AbstractMPS, ψ::AbstractMPS) - L = length(ψ) - T = promote_type(eltype(ψ), eltype(ϕ)) - S = typeof(similar(ψ[1], T, (1, 1))) - R = Vector{S}(undef, L+1) - R[end] = similar(ψ[1], T, (1, 1)) - R[end][1, 1] = one(T) - - for i ∈ L:-1:1 - M = ψ[i] - M̃ = conj.(ϕ[i]) - - D = R[i+1] - @tensor D[x, y] := M[x, σ, α] * D[α, β] * M̃[y, σ, β] order = (β, α, σ) - R[i] = D - end - R -end - -@memoize function right_env(ϕ::AbstractMPS{T}, W::AbstractMPO{T}, σ::Union{Vector, NTuple}) where {T} - l = length(σ) - #k = length(ϕ) - k = length(W) - if l == 0 - R = similar(ϕ[1], T, (1, 1)) - R[1, 1] = one(T) - else - m = σ[1] - R̃ = right_env(ϕ, W, σ[2:l]) - M = ϕ[k-l+1] - M̃ = W[k-l+1] - @reduce R[x, y] := sum(α, β, γ) M̃[y, $m, β, γ] * M[x, γ, α] * R̃[α, β] - end - R -end - - -""" -$(TYPEDSIGNATURES) - -Calculates the norm of an MPS \$\\ket{\\phi}\$ -""" -LinearAlgebra.norm(ψ::AbstractMPS) = sqrt(abs(dot(ψ, ψ))) - - -""" -$(TYPEDSIGNATURES) - -Calculates \$\\bra{\\phi} O \\ket{\\psi}\$ - -# Details - -Calculates the matrix element of \$O\$ -```math -\\bra{\\phi} O \\ket{\\psi} -``` -in one pass, utlizing `TensorOperations`. -""" - -function LinearAlgebra.dot(ϕ::AbstractMPS, O::Union{Vector, NTuple}, ψ::AbstractMPS) #where T <: AbstractMatrix - S = promote_type(eltype(ψ), eltype(ϕ), eltype(O[1])) - C = similar(ψ[1], S, (1, 1)) - C[1, 1] = one(S) - - for i ∈ eachindex(ψ) - M = ψ[i] - M̃ = conj.(ϕ[i]) - Mat = O[i] - @tensor C[x, y] := M̃[β, σ, x] * Mat[σ, η] * C[β, α] * M[α, η, y] order = (α, η, β, σ) - end - tr(C) -end - - -function LinearAlgebra.dot(O::AbstractMPO, ψ::AbstractMPS) - L = length(ψ) - S = promote_type(eltype(ψ), eltype(O)) - T = typeof(ψ) - ϕ = T.name.wrapper(S, L) - - for i ∈ 1:L - W = O[i] - M = ψ[i] - - @reduce N[(x, a), σ, (y, b)] := sum(η) W[x, σ, y, η] * M[a, η, b] - ϕ[i] = N - end - ϕ -end - -function dot!(ψ::AbstractMPS, O::AbstractMPO) - L = length(ψ) - for i ∈ 1:L - W = O[i] - M = ψ[i] - - @reduce N[(x, a), σ, (y, b)] := sum(η) W[x, σ, y, η] * M[a, η, b] - ψ[i] = N - end -end - -function LinearAlgebra.dot(O1::AbstractMPO, O2::AbstractMPO) - L = length(O1) - S = promote_type(eltype(O1), eltype(O2)) - T = typeof(O1) - O = T.name.wrapper(S, L) - - for i ∈ 1:L - W1 = O1[i] - W2 = O2[i] - @reduce V[(x, a), σ, (y, b), η] := sum(γ) W1[x, σ, y, γ] * W2[a, γ, b, η] - - O[i] = V - end - O -end - -Base.:(*)(A::AbstractTensorNetwork, B::AbstractTensorNetwork) = dot(A, B) diff --git a/src/exact.jl b/src/exact.jl deleted file mode 100644 index db3b4537..00000000 --- a/src/exact.jl +++ /dev/null @@ -1,50 +0,0 @@ -export gibbs_tensor -export brute_force, full_spectrum - -""" -$(TYPEDSIGNATURES) - -Calculates Gibbs state of a classical Ising Hamiltonian - -# Details - -Calculates matrix elements (probabilities) of \$\\rho\$ -```math -\$\\bra{\\σ}\\rho\\ket{\\sigma}\$ -``` -for all possible configurations \$\\σ\$. -""" -function gibbs_tensor(ig::MetaGraph, β=Float64=1.0) - states = collect.(all_states(rank_vec(ig))) - ρ = exp.(-β .* energy.(states, Ref(ig))) - ρ ./ sum(ρ) -end - -""" -$(TYPEDSIGNATURES) - -Return the low energy spectrum - -# Details - -Calculates \$k\$ lowest energy states -together with the coresponding energies -of a classical Ising Hamiltonian -""" - -function brute_force(ig::MetaGraph; sorted=true, num_states::Int=1) - if nv(ig) == 0 return Spectrum(zeros(1), []) end - ig_rank = rank_vec(ig) - num_states = min(num_states, prod(ig_rank)) - - σ = collect.(all_states(ig_rank)) - energies = energy.(σ, Ref(ig)) - if sorted - perm = partialsortperm(vec(energies), 1:num_states) - return Spectrum(energies[perm], σ[perm]) - else - return Spectrum(energies[1:num_states], σ[1:num_states]) - end -end - -full_spectrum(ig::MetaGraph; num_states::Int=1) = brute_force(ig, sorted=false, num_states=num_states) diff --git a/src/factor.jl b/src/factor.jl deleted file mode 100644 index a5155e1b..00000000 --- a/src/factor.jl +++ /dev/null @@ -1,103 +0,0 @@ -export factor_graph, rank_reveal, projectors, split_into_clusters - - -function split_into_clusters(vertices, assignment_rule) - # TODO: check how to do this in functional-style - clusters = Dict( - i => [] for i in values(assignment_rule) - ) - for v in vertices - push!(clusters[assignment_rule[v]], v) - end - clusters -end - -function split_into_clusters(ig::MetaGraph, assignment_rule) - cluster_id_to_verts = Dict( - i => Int[] for i in values(assignment_rule) - ) - - for (i, v) in enumerate(nodes(ig)) - push!(cluster_id_to_verts[assignment_rule[v]], i) - end - - return Dict( - i => cluster(ig, verts) for (i, verts) ∈ cluster_id_to_verts - ) -end - -function factor_graph( - ig::MetaGraph, - num_states_cl::Int; - energy::Function=energy, - spectrum::Function=full_spectrum, - cluster_assignment_rule::Dict{Int, Int} # e.g. square lattice -) - ns = Dict(i => num_states_cl for i ∈ Set(values(cluster_assignment_rule))) - factor_graph( - ig, - ns, - energy=energy, - spectrum=spectrum, - cluster_assignment_rule=cluster_assignment_rule - ) -end - -function factor_graph( - ig::MetaGraph, - num_states_cl::Dict{Int, Int}=Dict{Int, Int}(); - energy::Function=energy, - spectrum::Function=full_spectrum, - cluster_assignment_rule::Dict{Int, Int} # e.g. square lattice -) - L = maximum(values(cluster_assignment_rule)) - fg = MetaDiGraph(L) - - for (v, cl) ∈ split_into_clusters(ig, cluster_assignment_rule) - set_prop!(fg, v, :cluster, cl) - sp = spectrum(cl, num_states=get(num_states_cl, v, basis_size(cl))) - set_prop!(fg, v, :spectrum, sp) - set_prop!(fg, v, :loc_en, vec(sp.energies)) - set_prop!(fg, v, :loc_dim, length(vec(sp.energies))) - end - - for i ∈ 1:L, j ∈ i+1:L - v, w = get_prop(fg, i, :cluster), get_prop(fg, j, :cluster) - - outer_edges, J = inter_cluster_edges(ig, v, w) - - if !isempty(outer_edges) - en = inter_cluster_energy( - get_prop(fg, i, :spectrum).states, J, get_prop(fg, j, :spectrum).states - ) - - pl, en = rank_reveal(en, :PE) - en, pr = rank_reveal(en, :EP) - - add_edge!( - fg, i, j, - Dict(:outer_edges => outer_edges, :pl => pl, :en => en, :pr => pr) - ) - end - end - fg -end - -function rank_reveal(energy, order=:PE) - @assert order ∈ (:PE, :EP) - dim = order == :PE ? 1 : 2 - - E, idx = unique_dims(energy, dim) - - if order == :PE - P = zeros(size(energy, 1), size(E, 1)) - else - P = zeros(size(E, 2), size(energy, 2)) - end - - for (i, elements) ∈ enumerate(eachslice(P, dims=dim)) - elements[idx[i]] = 1 - end - - order == :PE ? (P, E) : (E, P) -end diff --git a/src/identities.jl b/src/identities.jl deleted file mode 100644 index b91270fd..00000000 --- a/src/identities.jl +++ /dev/null @@ -1,49 +0,0 @@ -export IdentityMPO, IdentityMPS -struct IdentityMPS{T <: Number, S <: AbstractArray} <: AbstractMPS{T} end -struct IdentityMPO{T <: Number, S <: AbstractArray} <: AbstractMPO{T} end -IdentityMPS() = IdentityMPS{Float64, Array}() -IdentityMPO() = IdentityMPO{Float64, Array}() - -IdentityMPS(::Type{T}) where {T <: AbstractArray} = IdentityMPS{Float64, T} -IdentityMPO(::Type{T}) where {T <: AbstractArray} = IdentityMPO{Float64, T} - -IdentityMPS(::Type{S}, ::Type{T}) where {S <: Number, T <: AbstractArray} = IdentityMPS{S, T} -IdentityMPO(::Type{S}, ::Type{T}) where {S <: Number, T <: AbstractArray} = IdentityMPO{S, T} - -const IdentityMPSorMPO = Union{IdentityMPO, IdentityMPS} - -@inline function Base.getindex(::IdentityMPS{S, T}, ::Int) where {S, T} - ret = similar(T{S}, (1, 1, 1)) - ret[1] = one(S) - ret -end - -@inline function Base.getindex(::IdentityMPO{S, T}, ::Int) where {S, T} - ret = similar(T{S}, (1, 1, 1, 1)) - ret[1] = one(S) - ret -end - -LinearAlgebra.dot(O::AbstractMPO, ::IdentityMPO) = O -LinearAlgebra.dot(::IdentityMPO, O::AbstractMPO) = O -Base.length(::IdentityMPSorMPO) = Inf - -function LinearAlgebra.dot(O::AbstractMPO, ::IdentityMPS) - L = length(O) - T = eltype(O) - ψ = MPS(T, L) #FIXME: this will fail with specialized MPS types - for i ∈ eachindex(ψ) - B = O[i] - @reduce A[x, σ, y] |= sum(η) B[x, σ, y, η] - ψ[i] = A - end - ψ -end - -LinearAlgebra.dot(::IdentityMPO, ψ::AbstractMPS) = ψ -LinearAlgebra.dot(ψ::AbstractMPS, ::IdentityMPO) = ψ - -function Base.show(io::IO, ::IdentityMPSorMPO) - println(io, "Trivial matrix product state") - println(io, " ") -end diff --git a/src/ising.jl b/src/ising.jl deleted file mode 100644 index f69b1f07..00000000 --- a/src/ising.jl +++ /dev/null @@ -1,123 +0,0 @@ -export ising_graph -export energy, rank_vec -export Spectrum, cluster, rank, nodes, basis_size - -const Instance = Union{String, Dict} - -struct Spectrum - energies::Vector{Float64} - states::Vector{Vector{Int}} -end - -unique_nodes(ising_tuples) = sort(collect(Set(Iterators.flatten((i, j) for (i, j, _) ∈ ising_tuples)))) - -""" -$(TYPEDSIGNATURES) - -Create the Ising spin glass model. - -# Details - -Store extra information -""" -function ising_graph( - instance::Instance, - sgn::Number=1.0, - rank_override::Dict{Int, Int}=Dict{Int, Int}() -) - # load the Ising instance - if instance isa String - ising = CSV.File(instance, types = [Int, Int, Float64], header=0, comment = "#") - else - ising = [ (i, j, J) for ((i, j), J) ∈ instance ] - end - - original_nodes = unique_nodes(ising) - L = length(original_nodes) - nodes_to_vertices = Dict(w => i for (i, w) ∈ enumerate(original_nodes)) - - ig = MetaGraph(length(original_nodes)) - - foreach(args -> set_prop!(ig, args[1], :node, args[2]), enumerate(original_nodes)) - - J = zeros(L, L) - h = zeros(L) - - # setup the model (J_ij, h_i) - for (_i, _j, v) ∈ ising - i, j = nodes_to_vertices[_i], nodes_to_vertices[_j] - v *= sgn - - if i == j - h[i] = v - else - add_edge!(ig, i, j, :J, v) || throw(ArgumentError("Duplicate Egde ($i, $j)")) - J[i, j] = v - end - end - - foreach(i -> set_prop!(ig, i, :h, h[i]), vertices(ig)) - - set_prop!( - ig, - :rank, - Dict{Int, Int}( - v => get(rank_override, w, 2) for (w, v) in nodes_to_vertices - ) - ) - - set_prop!(ig, :J, J) - set_prop!(ig, :h, h) - set_prop!(ig, :nodes_map, nodes_to_vertices) - ig -end - -nodes(ig::MetaGraph) = collect(get_prop.(Ref(ig), vertices(ig), :node)) -rank_vec(ig::MetaGraph) = collect(values(get_prop(ig, :rank))) -basis_size(ig::MetaGraph) = prod(prod(rank_vec(ig))) - -function cluster(ig::MetaGraph, verts) - sub_ig, vmap = induced_subgraph(ig, collect(verts)) - - h = get_prop.(Ref(sub_ig), vertices(sub_ig), :h) - rank = getindex.(Ref(get_prop(ig, :rank)), vmap) - J = get_prop(ig, :J)[vmap, vmap] - - set_props!(sub_ig, Dict(:rank => rank, :J => J, :h => h, :vmap => vmap)) - sub_ig -end - -function inter_cluster_edges(ig::MetaGraph, cl1::MetaGraph, cl2::MetaGraph) - verts1, verts2 = get_prop(cl1, :vmap), get_prop(cl2, :vmap) - outer_edges = filter_edges( - ig, - (_, e) -> (src(e) ∈ verts1 && dst(e) ∈ verts2) || - (src(e) ∈ verts1 && dst(e) ∈ verts2) - ) - J = zeros(nv(cl1), nv(cl2)) - # FIXME: don't use indexin - for e ∈ outer_edges - @inbounds J[indexin(src(e), verts1)[1], indexin(dst(e), verts2)[1]] = get_prop(ig, e, :J) - end - outer_edges, J -end - -""" -$(TYPEDSIGNATURES) - -Calculate the Ising energy -```math -E = -\\sum_ s_i J_{ij} * s_j - \\sum_j h_i s_j. -``` -""" - -energy(σ::Vector, J::Matrix, η::Vector=σ) = dot(σ, J, η) -energy(σ::Vector, h::Vector) = dot(h, σ) -energy(σ::Vector, ig::MetaGraph) = energy(σ, get_prop(ig, :J)) + energy(σ, get_prop(ig, :h)) - - -# Please don't make the below another energy method. -# There is already so much mess going on :) -function inter_cluster_energy(cl1_states, J::Matrix, cl2_states) - hcat(collect.(cl1_states)...)' * J * hcat(collect.(cl2_states)...) -end diff --git a/src/lattice.jl b/src/lattice.jl deleted file mode 100644 index b55ab54f..00000000 --- a/src/lattice.jl +++ /dev/null @@ -1,17 +0,0 @@ -export super_square_lattice - - function super_square_lattice(size::NTuple{5, Int}) - m, um, n, un, t = size - new = LinearIndices((1:n, 1:m)) - old = LinearIndices((1:t, 1:un, 1:n, 1:um, 1:m)) - - Dict( - old[k, uj, j, ui, i] => new[j, i] - for i=1:m, ui=1:um, j=1:n, uj=1:un, k=1:t - ) -end - -function super_square_lattice(size::NTuple{3, Int}) - m, n, t = size - super_square_lattice((m, 1, n, 1, t)) -end diff --git a/src/search.jl b/src/search.jl deleted file mode 100644 index 13ce3063..00000000 --- a/src/search.jl +++ /dev/null @@ -1,92 +0,0 @@ -export AbstractGibbsNetwork -export low_energy_spectrum -export Solution - -abstract type AbstractGibbsNetwork end - -struct Solution - energies::Vector{Float64} - states::Vector{Vector{Int}} - probabilities::Vector{Float64} - largest_discarded_probability::Float64 -end - -#TODO: this can probably be done better -function _branch_state( - cfg::Vector, - state::Vector, - basis::Vector, - ) - tmp = Vector{Int}[] - for σ ∈ basis push!(tmp, vcat(state, σ)) end - vcat(cfg, tmp) -end - -# TODO: logic here can probably be done better -function _bound(probabilities::Vector{Float64}, cut::Int) - k = length(probabilities) - second_phase = false - - if k > cut + 1 - k = cut + 1 - second_phase = true - end - - idx = partialsortperm(probabilities, 1:k, rev=true) - - if second_phase - return idx[1:end-1], probabilities[last(idx)] - else - return idx, -Inf - end -end - -function _branch_and_bound( - sol::Solution, - network::AbstractGibbsNetwork, - node::Int, - cut::Int, - ) - - # branch - pdo, eng, cfg = Float64[], Float64[], Vector{Int}[] - - k = get_prop(network.fg, node, :loc_dim) - - for (p, σ, e) ∈ zip(sol.probabilities, sol.states, sol.energies) - pdo = [pdo; p .* conditional_probability(network, σ)] - eng = [eng; e .+ update_energy(network, σ)] - cfg = _branch_state(cfg, σ, collect(1:k)) - end - - # bound - indices, lowest_prob = _bound(pdo, cut) - lpCut = sol.largest_discarded_probability - lpCut < lowest_prob ? lpCut = lowest_prob : () - - Solution(eng[indices], cfg[indices], pdo[indices], lpCut) -end - -#TODO: incorporate "going back" move to improve alghoritm -function low_energy_spectrum( - network::AbstractGibbsNetwork, - cut::Int -) - sol = Solution([0.], [[]], [1.], -Inf) - - perm = zeros(Int, nv(network.fg)) # TODO: to be removed - - #TODO: this should be replaced with the iteration over fg that is consistent with the order network - for i ∈ 1:network.i_max, j ∈ 1:network.j_max - v_fg = network.map[i, j] - perm[v_fg] = j + network.j_max * (i - 1) - sol = _branch_and_bound(sol, network, v_fg, cut) - end - K = partialsortperm(sol.energies, 1:length(sol.energies), rev=false) - - Solution( - sol.energies[K], - [ σ[perm] for σ ∈ sol.states[K] ], #TODO: to be changed - sol.probabilities[K], - sol.largest_discarded_probability) -end diff --git a/src/utils.jl b/src/utils.jl deleted file mode 100644 index 504f38b9..00000000 --- a/src/utils.jl +++ /dev/null @@ -1,137 +0,0 @@ -export idx, ising, proj -export HadamardMPS, rq -export all_states, local_basis -export unique_neighbors, peps_indices - -using Base.Cartesian -import Base.Prehashed - -idx(σ::Int) = (σ == -1) ? 1 : σ + 1 - -local_basis(d::Int) = union(-1, 1:d-1) -local_basis(ψ::AbstractMPS, i::Int) = local_basis(physical_dim(ψ, i)) - -function all_states(rank::Union{Vector, NTuple}) - basis = [local_basis(r) for r ∈ rank] - product(basis...) -end - -function HadamardMPS(::Type{T}, rank::Union{Vector, NTuple}) where {T <: Number} - vec = [ fill(one(T), r) ./ sqrt(T(r)) for r ∈ rank ] - MPS(vec) -end -HadamardMPS(rank::Union{Vector, NTuple}) = HadamardMPS(Float64, rank) - -function LinearAlgebra.qr(M::AbstractMatrix, Dcut::Int, args...) - fact = pqrfact(M, rank=Dcut, args...) - Q = fact[:Q] - R = fact[:R] - return _qr_fix(Q, R) -end - -function rq(M::AbstractMatrix, Dcut::Int, args...) - fact = pqrfact(:c, conj.(M), rank=Dcut, args...) - Q = fact[:Q] - R = fact[:R] - return _qr_fix(Q, R)' -end - -function _qr_fix(Q::T, R::AbstractMatrix) where {T <: AbstractMatrix} - d = diag(R) - ph = d./abs.(d) - idim = size(R, 1) - q = T.name.wrapper(Q)[:, 1:idim] - return transpose(ph) .* q -end - -function LinearAlgebra.svd(A::AbstractMatrix, Dcut::Int, args...) - U, Σ, V = psvd(A, rank=Dcut, args...) - d = diag(U) - ph = d ./ abs.(d) - return U * Diagonal(ph), Σ, V * Diagonal(ph) -end - -@generated function unique_dims(A::AbstractArray{T,N}, dim::Integer) where {T,N} - quote - 1 <= dim <= $N || return copy(A) - hashes = zeros(UInt, axes(A, dim)) - - # Compute hash for each row - k = 0 - @nloops $N i A d->(if d == dim; k = i_d; end) begin - @inbounds hashes[k] = hash(hashes[k], hash((@nref $N A i))) - end - - # Collect index of first row for each hash - uniquerow = similar(Array{Int}, axes(A, dim)) - firstrow = Dict{Prehashed,Int}() - for k = axes(A, dim) - uniquerow[k] = get!(firstrow, Prehashed(hashes[k]), k) - end - uniquerows = collect(values(firstrow)) - - # Check for collisions - collided = falses(axes(A, dim)) - @inbounds begin - @nloops $N i A d->(if d == dim - k = i_d - j_d = uniquerow[k] - else - j_d = i_d - end) begin - if (@nref $N A j) != (@nref $N A i) - collided[k] = true - end - end - end - - if any(collided) - nowcollided = similar(BitArray, axes(A, dim)) - while any(collided) - # Collect index of first row for each collided hash - empty!(firstrow) - for j = axes(A, dim) - collided[j] || continue - uniquerow[j] = get!(firstrow, Prehashed(hashes[j]), j) - end - for v ∈ values(firstrow) - push!(uniquerows, v) - end - - # Check for collisions - fill!(nowcollided, false) - @nloops $N i A d->begin - if d == dim - k = i_d - j_d = uniquerow[k] - (!collided[k] || j_d == k) && continue - else - j_d = i_d - end - end begin - if (@nref $N A j) != (@nref $N A i) - nowcollided[k] = true - end - end - (collided, nowcollided) = (nowcollided, collided) - end - end - - (@nref $N A d->d == dim ? sort!(uniquerows) : (axes(A, d))), indexin(uniquerow, uniquerows) - end -end - -""" -$(TYPEDSIGNATURES) - -Calculate unique neighbors of node \$i\$ - -# Details - -This is equivalent of taking the upper -diagonal of the adjacency matrix -""" -function unique_neighbors(ig::MetaGraph, i::Int) - nbrs = neighbors(ig::MetaGraph, i::Int) - filter(j -> j > i, nbrs) -end diff --git a/test/MPS_search.jl b/test/MPS_search.jl deleted file mode 100644 index 570c55f6..00000000 --- a/test/MPS_search.jl +++ /dev/null @@ -1,125 +0,0 @@ -using MetaGraphs -using LightGraphs -using GraphPlot - -# This a semi-finished cleaning of this file - -L = 2 -N = L^2 - -instance = "$(@__DIR__)/instances/$(N)_001.txt" - -# This is a mess, and it should be cleand up -ig = ising_graph(instance) -r = fill(2, N) -set_prop!(ig, :rank, r) -dβ = 0.01 -β = 1 - -ϵ = 1E-8 -D = prod(r) + 1 -var_ϵ = 1E-8 -sweeps = 4 - -# MPSControl should be removed -control = MPSControl(D, var_ϵ, sweeps, β, dβ) -states = all_states(get_prop(ig, :rank)) - - -@testset "Generating MPS" begin - ϱ = gibbs_tensor(ig, β) - - @testset "Sqrt of the Gibbs state (aka state tensor)" begin - L = nv(ig) - rank = get_prop(ig, :rank) - - ψ = ones(rank...) - for σ ∈ states - for i ∈ 1:L - h = get_prop(ig, i, :h) - - nbrs = unique_neighbors(ig, i) - ψ[idx.(σ)...] *= exp(-0.5 * β * h * σ[i]) - - for j ∈ nbrs - J = get_prop(ig, i, j, :J) - ψ[idx.(σ)...] *= exp(-0.5 * β * σ[i] * J * σ[j]) - end - end - end - - ρ = abs.(ψ) .^ 2 - rψ = MPS(ψ) - lψ = MPS(ψ, :left) - - @testset "produces correct Gibbs state" begin - @test ρ / sum(ρ) ≈ ϱ - end - - @testset "MPS from the tensor" begin - - @testset "can be right normalized" begin - @test dot(rψ, rψ) ≈ 1 - @test_nowarn is_right_normalized(rψ) - end - - @testset "can be left normalized" begin - @test dot(lψ, lψ) ≈ 1 - @test_nowarn is_left_normalized(lψ) - end - - @testset "both forms are the same (up to a phase factor)" begin - vlψ = vec(tensor(lψ)) - vrψ = vec(tensor(rψ)) - - vψ = vec(ψ) - vψ /= norm(vψ) - - @test abs(1 - abs(dot(vlψ, vrψ))) < ϵ - @test abs(1 - abs(dot(vlψ, vψ))) < ϵ - end - end - - @testset "MPS from gates" begin - Gψ = MPS(ig, control) - - @testset "is built correctly" begin - @test abs(1 - abs(dot(Gψ, rψ))) < ϵ - end - - @testset "is normalized" begin - @test dot(Gψ, Gψ) ≈ 1 - @test_nowarn is_right_normalized(Gψ) - end - - @testset "has correct links and non-trivial bond dimension" begin - @test bond_dimension(Gψ) > 1 - @test_nowarn verify_bonds(Gψ) - end - end - - @testset "Exact probabilities are calculated correctely" begin - for σ ∈ states - p, r = dot(rψ, σ), dot(rψ, proj(σ, rank), rψ) - @test p ≈ r - @test ϱ[idx.(σ)...] ≈ p - end - end - - @testset "Results from solve agree with brute-force" begin - # The energy is wrong when max_states > N^2-2 - - for max_states ∈ [1, N, 2*N, 3*N, N^2-3, N^2-2]#, N^2-1, N^2] - states, prob, pCut = solve(rψ, max_states) - sp = brute_force(ig, num_states = max_states) - - for (j, (p, e)) ∈ enumerate(zip(prob, sp.energies)) - σ = states[j, :] - @test e ≈ energy(σ, ig) - @test log(ϱ[idx.(σ)...]) ≈ p - end - end - end - - end -end diff --git a/test/PEPS.jl b/test/PEPS.jl deleted file mode 100644 index 4929263c..00000000 --- a/test/PEPS.jl +++ /dev/null @@ -1,57 +0,0 @@ - -@testset "peps_indices correctly assigns indices" begin -m = 3 -n = 4 - -origin_l = [:NW, :NE, :SE, :SW] -origin_r = [:WN, :EN, :ES, :WS] - -for (ol, or) ∈ zip(origin_l, origin_r) - ind_l, i_max_l, j_max_l = peps_indices(m, n, ol) - ind_r, i_max_r, j_max_r = peps_indices(m, n, or) - - @test i_max_l == m == j_max_r - @test j_max_l == n == i_max_r - - for i ∈ 0:m+1, j ∈ 0:n+1 - @test ind_l[i, j] == ind_r[j, i] - end -end -end - -@testset "PepsTensor correctly builds PEPS network" begin - -m = 3 -n = 4 -t = 3 - -β = 1 - -L = m * n * t -T = Float64 - -instance = "$(@__DIR__)/instances/pathological/test_$(m)_$(n)_$(t).txt" - -ig = ising_graph(instance) - - -fg = factor_graph( - ig, - energy=energy, - spectrum=full_spectrum, - cluster_assignment_rule=super_square_lattice((m, n, t)) -) - -x, y = m, n - -for origin ∈ (:NW, :SW, :WS, :WN, :NE, :EN, :SE, :ES) - peps = PEPSNetwork(x, y, fg, β, origin) - - ψ = IdentityMPS() - for i ∈ peps.i_max:-1:1 - ψ = MPO(T, peps, i) * ψ - @test MPS(peps, i) ≈ ψ - end -end - -end diff --git a/test/base.jl b/test/base.jl deleted file mode 100644 index d2cb462b..00000000 --- a/test/base.jl +++ /dev/null @@ -1,181 +0,0 @@ -@testset "MPS" begin - -D = 10 -d = 4 -sites = 5 -T = ComplexF64 - -@testset "Random MPS with the same physical dimension" begin - - ψ = randn(MPS{T}, sites, D, d) - - @testset "has correct number of sites" begin - @test length(ψ) == sites - @test size(ψ) == (sites, ) - end - - @testset "has correct type" begin - @test eltype(ψ) == T - end - - @testset "has correct rank" begin - @test rank(ψ) == Tuple(fill(d, 1:sites)) - end - - @testset "has correct bonds" begin - @test bond_dimension(ψ) ≈ D - @test verify_bonds(ψ) === nothing - end - - @testset "is equal to itself" begin - @test ψ == ψ - @test ψ ≈ ψ - end - - @testset "is equal to its copy" begin - ϕ = copy(ψ) - @test ϕ == ψ - @test ϕ ≈ ψ - end -end - -@testset "Random MPS with varying physical dimension" begin - - dims = (3, 2, 5, 4) - ψ = randn(MPS{T}, D, dims) - - @testset "has correct number of sites" begin - n = length(dims) - @test length(ψ) == n - @test size(ψ) == (n, ) - end - - @testset "has correct type" begin - @test eltype(ψ) == T - end - - @testset "has correct rank" begin - @test rank(ψ) == dims - end - - @testset "has correct bonds" begin - @test bond_dimension(ψ) ≈ D - @test verify_bonds(ψ) === nothing - end - - @testset "is equal to itself" begin - @test ψ == ψ - @test ψ ≈ ψ - end - - @testset "is equal to its copy" begin - ϕ = copy(ψ) - @test ϕ == ψ - @test ϕ ≈ ψ - end -end - -@testset "Random MPO with the same physical dimension" begin - - W = randn(MPO{T}, sites, D, d) - - @testset "has correct number of sites" begin - @test length(W) == sites - @test size(W) == (sites, ) - end - - @testset "has correct type" begin - @test eltype(W) == T - end - - @testset "is equal to itself" begin - @test W == W - @test W ≈ W - end - - @testset "is equal to its copy" begin - U = copy(W) - @test U == W - @test U ≈ W - end -end - -# @testset "Random MPO with varying physical dimension" begin - -# dims = (3, 2, 5, 4) -# W = randn(MPO{T}, D, dims) - -# @testset "has correct number of sites" begin -# n = length(dims) -# @test length(W) == n -# @test size(W) == (n, ) -# end - -# @testset "has correct type" begin -# @test eltype(W) == T -# end - -# @testset "is equal to itself" begin -# @test W == W -# @test W ≈ W -# end - -# @testset "is equal to its copy" begin -# U = copy(W) -# @test U == W -# @test U ≈ W -# end -# end - -@testset "MPS from tensor" begin - ϵ = 1E-14 - - dims = (2,3,4,3,5) - sites = length(dims) - A = randn(T, dims) - - ψ = MPS(A, :right) - - @test norm(ψ) ≈ 1 - @test_nowarn verify_bonds(ψ) - @test_nowarn verify_physical_dims(ψ, dims) - @test is_right_normalized(ψ) - - # from here - move to the attic - AA = tensor(ψ) - - @test rank(ψ) == size(AA) - @test norm(AA) ≈ 1 - @test size(AA) == size(A) - - vA = vec(A) - nA = norm(vA) - @test abs(1 - abs(dot(vec(AA), vA ./ nA))) < ϵ - #@test AA ≈ A ./ norm(A) # this is true "module phase" - - B = randn(T, dims...) - ϕ = MPS(B, :left) - - @test norm(ϕ) ≈ 1 - @test_nowarn verify_bonds(ϕ) - @test_nowarn verify_physical_dims(ϕ, dims) - @test is_left_normalized(ϕ) - - BB = tensor(ϕ) - - @test rank(ϕ) == size(BB) - @test norm(BB) ≈ 1 - @test sqrt(sum(abs.(B) .^ 2)) ≈ norm(B) - - vB = vec(B) - nB = norm(vB) - @test abs(1 - abs(dot(vec(BB), vB ./ nB))) < ϵ - #@test BB ≈ B ./ norm(B) # this is true "module phase" - - χ = MPS(A, :left) - - @test norm(χ) ≈ 1 - @test abs(1 - abs(dot(ψ, χ))) < ϵ -end - -end diff --git a/test/compressions.jl b/test/compressions.jl deleted file mode 100644 index 4595981f..00000000 --- a/test/compressions.jl +++ /dev/null @@ -1,80 +0,0 @@ -@testset "Canonisation and Compression" begin - -D = 10 -Dcut = 5 - -d = 2 -sites = 5 - -T = Float64 - -ψ = randn(MPS{T}, sites, D, d) -ϕ = randn(MPS{T}, sites, D, d) -χ = randn(MPS{T}, sites, D, d) -Φ = randn(MPS{T}, sites, D, d) - -@testset "Canonisation (left)" begin - canonise!(ψ, :left) - @test is_left_normalized(ψ) - @test dot(ψ, ψ) ≈ 1 -end - -@testset "Canonisation (right)" begin - canonise!(ϕ, :right) - @test is_right_normalized(ϕ) - @test dot(ϕ, ϕ) ≈ 1 -end - -@testset "Cauchy-Schwarz inequality (after truncation)" begin - @test abs(dot(ϕ, ψ)) <= norm(ϕ) * norm(ψ) -end - -@testset "Canonisation (both)" begin - canonise!(χ) - @test dot(χ, χ) ≈ 1 -end - -@testset "Truncation (SVD, right)" begin - truncate!(ψ, :right, Dcut) - @test dot(ψ, ψ) ≈ 1 -end - -@testset "Truncation (SVD, left)" begin - truncate!(ψ, :left, Dcut) - @test dot(ψ, ψ) ≈ 1 -end - -@testset "" begin - ϵ = 1E-14 - ψ = randn(MPS{T}, sites, D, d) - - l = copy(ψ) - r = copy(l) - canonise!(l, :left) - canonise!(r, :right) - - @test dot(l, l) ≈ 1 - @test dot(r, r) ≈ 1 - - @test abs(1 - abs(dot(l, r))) < ϵ -end - -@testset "Variational compression" begin - Dcut = 5 - tol = 1E-4 - max_sweeps = 5 - - canonise!(Φ, :right) - @test dot(Φ, Φ) ≈ 1 - - Ψ = compress(Φ, Dcut, tol, max_sweeps) - - @test dot(Ψ, Ψ) ≈ 1 - - overlap = dot(Ψ, Φ) - dist1 = 2 - 2 * abs(overlap) - dist2 = norm(Ψ)^2 + norm(Φ)^2 - 2 * abs(overlap) - - @test abs(dist1 - dist2) < 1e-14 -end -end diff --git a/test/contract.jl b/test/contract.jl deleted file mode 100644 index 8c021252..00000000 --- a/test/contract.jl +++ /dev/null @@ -1,54 +0,0 @@ -@testset "peps_contract correctly collapse the peps network" begin - - # Grid - # A1 | A2 - # | - # 1 -- 2 -|- 3 - - D = Dict((1, 2) => -0.9049, - (2, 3) => 0.2838, - - (3, 3) => -0.7928, - (2, 2) => 0.1208, - (1, 1) => -0.3342 - ) - - m, n = 1, 2 - L = 4 - β = 1. - - ig = ising_graph(D) - - fg = factor_graph( - ig, - Dict(1 => 4, 2 => 2), - energy = energy, - spectrum = full_spectrum, - cluster_assignment_rule = Dict(1 => 1, 2 => 1, 3 => 2, 4 => 2) - ) - - e, p = get_prop(fg, 1, 2, :en), get_prop(fg, 1, 2, :pr) - ϕ = exp(β * minimum(e * p)) - - for i ∈ 1:4, j ∈ 1:2 - cfg = Dict(1 => i, 2 => j) - - Z = [] - for origin ∈ (:NW, :SW, :WS, :WN) - peps = PEPSNetwork(m, n, fg, β, origin) - p = contract_network(peps, cfg) - push!(Z, p) - end - - # they all should be the same - @test all(x -> x ≈ first(Z), Z) - - # the exact Gibbs state - states = collect.(all_states(rank_vec(ig))) - ρ = exp.(-β .* energy.(states, Ref(ig))) - ϱ = reshape(ρ, (4, 2)) * ϕ - - # probabilities should agree - @test first(Z) ≈ ϱ[cfg[1], cfg[2]] - end -end diff --git a/test/contractions.jl b/test/contractions.jl deleted file mode 100644 index 152f02f5..00000000 --- a/test/contractions.jl +++ /dev/null @@ -1,103 +0,0 @@ -@testset "contractions" begin - -D = 10 -d = 3 -sites = 5 -T = ComplexF64 - -ψ = randn(MPS{T}, sites, D, d) -ϕ = randn(MPS{T}, sites, D, d) -mpo_ψ = randn(MPO{T}, sites, D, d) -mpo = randn(MPO{T}, 2, 2, 2) - - -Id = fill(I(d), length(ψ)) - -Id_m = MPO(fill(ones(1,1,1,d), length(ϕ))) - -@testset "dot products" begin - @testset "is equal to itself" begin - @test dot(ψ, ψ) ≈ dot(ψ, ψ) - end - - @testset "change of arguments results in conjugation" begin - @test dot(ψ, ϕ) ≈ conj(dot(ϕ, ψ)) - @test dot(ψ, Id, ϕ) ≈ conj(dot(ϕ, Id, ψ)) - end - - @testset "dot with identity equal to dot of two MPS" begin - @test dot(ψ, Id, ϕ) ≈ dot(ψ, ϕ) - end - - @testset "norm is 2-norm" begin - @test norm(ψ) ≈ sqrt(abs(dot(ψ, ψ))) - end - - @testset "renormalizations" begin - ψ[end] *= 1/norm(ψ) - @test dot(ψ, ψ) ≈ 1 - - ϕ[1] *= 1/norm(ϕ) - @test dot(ϕ, ϕ) ≈ 1 - end - - @testset "dot products of MPO" begin - mpo1 = dot(mpo, mpo) - - @testset "has correct sisze" begin - @test size(mpo1[1]) == (1, 2, 4, 2) - @test size(mpo1[2]) == (4, 2, 1, 2) - end - end - -end - -@testset "left environment" begin - L = left_env(ϕ, ψ) - @test L[end][1] ≈ dot(ϕ, ψ) -end - -@testset "right environment" begin - R = right_env(ϕ, ψ) - @test R[1][end] ≈ dot(ϕ, ψ) -end - -@testset "Cauchy-Schwarz inequality of MPS" begin - @test abs(dot(ϕ, ψ)) <= norm(ϕ) * norm(ψ) -end - - -@testset "left_env correctly contracts MPS for a given configuration" begin - D = 10 - d = 2 - sites = 5 - T = ComplexF64 - - ψ = randn(MPS{T}, sites, D, d) - σ = 2 * (rand(sites) .< 0.5) .- 1 - - @test tensor(ψ, σ) ≈ left_env(ψ, map(idx, σ))[] -end - -@testset "right_env correctly contracts MPO with MPS for a given configuration" begin - D = 10 - d = 2 - sites = 5 - T = Float64 - - ψ = randn(MPS{T}, sites, D, d) - W = randn(MPO{T}, sites, D, d) - - σ = 2 * (rand(sites) .< 0.5) .- 1 - - ϕ = MPS(T, sites) - for (i, A) ∈ enumerate(W) - m = idx(σ[i]) - @cast B[x, s, y] := A[x, $m, y, s] - ϕ[i] = B - end - - @test dot(ψ, ϕ) ≈ right_env(ψ, W, map(idx, σ))[] -end - -end diff --git a/test/factor.jl b/test/factor.jl deleted file mode 100644 index 5b5fd603..00000000 --- a/test/factor.jl +++ /dev/null @@ -1,216 +0,0 @@ -using MetaGraphs -using LightGraphs -using GraphPlot -using CSV - -@testset "split_into_clusters correctly assings vertices to clusters" begin - rule = Dict( - 1 => 1, - 2 => 1, - 3 => 3, - 4 => 2, - 5 => 3, - 6 => 4 - ) - vertices = [1, 3, 4, 5] - expected_result = Dict( - 1 => [1], 2 => [4], 3 => [3, 5], 4 => [] - ) - - @test split_into_clusters(vertices, rule) == expected_result -end - -@testset "Lattice graph" begin - m = 4 - n = 4 - t = 4 - L = 128 - - instance = "$(@__DIR__)/instances/chimera_droplets/$(L)power/001.txt" - - ig = ising_graph(instance) - - fg = factor_graph( - ig, 2, cluster_assignment_rule=super_square_lattice((m, n, 2*t)) - ) - - @test collect(vertices(fg)) == collect(1:m * n) - - @info "Verifying cluster properties for Lattice" m, n, t - - clv = [] - cle = [] - rank = rank_vec(ig) - - for v ∈ vertices(fg) - cl = get_prop(fg, v, :cluster) - - vmap = get_prop(cl, :vmap) - push!(clv, vmap) - push!(cle, collect(edges(cl))) - - for (i, v) in enumerate(vmap) - @test rank_vec(cl)[i] == rank[v] - end - end - - # Check if graph is factored correctly - @test isempty(intersect(clv...)) -# @test isempty(intersect(cle...)) -end - -@testset "Factor graph builds on pathological instance" begin -m = 3 -n = 4 -t = 3 -L = n * m * t - -instance = "$(@__DIR__)/instances/pathological/test_$(m)_$(n)_$(t).txt" - -ising = CSV.File(instance, types=[Int, Int, Float64], header=0, comment = "#") - -couplings = Dict() -for (i, j, v) ∈ ising - push!(couplings, (i, j) => v) -end - -cedges = Dict( - (1, 2) => [(1, 4), (1, 5), (1, 6)], - (1, 5) => [(1, 13)], - (2, 3) => [(4, 7), (5, 7), (6, 8), (6, 9)], - (2, 6) => [(6, 16), (6, 18), (5, 16)], - (5, 6) => [(13, 16), (13, 18)], - (6, 10) => [(18, 28)], - (10, 11) => [(28, 31), (28, 32), (28, 33), (29, 31), (29, 32), (29, 33), (30, 31), (30, 32), (30, 33)] -) - -cells = Dict( - 1 => [1], - 2 => [4, 5, 6], - 3 => [7, 8, 9], - 4 => [], - 5 => [13], - 6 => [16, 18], - 7 => [], - 8 => [], - 9 => [], - 10 => [28, 29, 30], - 11 => [31, 32, 33], - 12 => [] -) - -d = 2 -rank = Dict( - c => fill(d, length(idx)) - for (c,idx) ∈ cells if !isempty(idx) -) - -bond_dimensions = [2, 2, 8, 4, 2, 2, 8] - -ig = ising_graph(instance) - - -fg = factor_graph( - ig, - energy=energy, - spectrum=full_spectrum, - cluster_assignment_rule=super_square_lattice((m, n, t)), -) - -for v ∈ vertices(fg) - cl = get_prop(fg, v, :cluster) - @test sort(collect(nodes(cl))) == cells[v] -end - - -for (bd, e) in zip(bond_dimensions, edges(fg)) - pl, en, pr = get_prop(fg, e, :pl), get_prop(fg, e, :en), get_prop(fg, e, :pr) - @test minimum(size(en)) == bd -end - -for ((i, j), cedge) ∈ cedges - pl, en, pr = get_prop(fg, i, j, :pl), get_prop(fg, i, j, :en), get_prop(fg, i, j, :pr) - - base_i = all_states(rank[i]) - base_j = all_states(rank[j]) - - idx_i = enum(cells[i]) - idx_j = enum(cells[j]) - - # Change it to test if energy is calculated using passed 'energy' function - energy = zeros(prod(rank[i]), prod(rank[j])) - - for (ii, σ) ∈ enumerate(base_i) - for (jj, η) ∈ enumerate(base_j) - eij = 0. - for (k, l) ∈ values(cedge) - kk, ll = enum(cells[i])[k], enum(cells[j])[l] - s, r = σ[idx_i[k]], η[idx_j[l]] - J = couplings[k, l] - eij += s * J * r - end - energy[ii, jj] = eij - end - end - @test energy ≈ pl * (en * pr) -end - -@testset "each cluster comprises expected cells" begin -for v ∈ vertices(fg) - cl = get_prop(fg, v, :cluster) - - @test issetequal(nodes(cl), cells[v]) -end -end - -@testset "each edge comprises expected bunch of edges from source Ising graph" begin -for e ∈ edges(fg) - outer_edges = get_prop(fg, e, :outer_edges) - # println(collect(outer_edges)) - # println(cedges[Tuple(e)]) - # Note: this test is ok if we translate edges correctly. - # TODO: fix this by translating from nodes to graph coordinates - # @test issetequal(cedges[Tuple(e)], collect(outer_edges)) -end -end - -end - - -@testset "Rank reveal correctly decomposes energy row-wise" begin - energy = [[1 2 3]; [0 -1 0]; [1 2 3]] - P, E = rank_reveal(energy, :PE) - @test size(P) == (3, 2) - @test size(E) == (2, 3) - @test P * E ≈ energy -end - -@testset "Rank reveal correctly decomposes energy column-wise" begin - energy = [[1, 2, 3] [0, -1, 1] [1, 2, 3]] - E, P = rank_reveal(energy, :EP) - @test size(P) == (2, 3) - @test size(E) == (3, 2) - @test E * P ≈ energy -end - -@testset "Rank reveal correctly decomposes energy into projector, energy, projector" begin - #energy = [[1 2 3]; [0 -1 0]; [1 2 3]] - energy = [[1.0 -0.5 1.5 0.0 0.0 -1.5 0.5 -1.0]; - [0.0 0.5 0.5 1.0 -1.0 -0.5 -0.5 0.0]; - [0.5 0.0 1.0 0.5 -0.5 -1.0 0.0 -0.5]; - [-0.5 1.0 0.0 1.5 -1.5 0.0 -1.0 0.5]; - [0.5 -1.0 0.0 -1.5 1.5 0.0 1.0 -0.5]; - [-0.5 0.0 -1.0 -0.5 0.5 1.0 0.0 0.5]; - [0.0 -0.5 -0.5 -1.0 1.0 0.5 0.5 0.0]; - [-1.0 0.5 -1.5 0.0 0.0 1.5 -0.5 1.0]] - Pl, E_old = rank_reveal(energy, :PE) - @test size(Pl) == (8, 8) - @test size(E_old) == (8, 8) - @test Pl * E_old ≈ energy - - E, Pr = rank_reveal(E_old, :EP) - @test size(Pr) == (8, 8) - @test size(E) == (8, 8) - @test E * Pr ≈ E_old - @test Pl * E * Pr ≈ energy -end diff --git a/test/identities.jl b/test/identities.jl deleted file mode 100644 index d001a17e..00000000 --- a/test/identities.jl +++ /dev/null @@ -1,61 +0,0 @@ -ψ = randn(MPS{Float64}, 4, 3, 2) -O = randn(MPO{Float64}, 4, 3, 2) - -IMPS = IdentityMPS() -IMPO = IdentityMPO() - -@testset "multiplication of IdentityMPO" begin - - @testset "mutlitplication with MPS ψ returns ψ" begin - @test IMPO * ψ == ψ - @test ψ * IMPO == ψ - end - - @testset "mutlitplication with MPO O returns O" begin - @test IMPO * O == O - end -end - -@testset "Multiplication of IdentityMPS by an MPO O" begin - ϕ = O * IMPS - - @testset "result has the correct type" begin - @test typeof(ϕ) == MPS{Float64} - end - - @testset "length of result is the same as O" begin - @test length(ϕ) == length(O) - end - - @testset "the multiplication drops the correct dims" begin - for i ∈ eachindex(O) - @test ϕ[i] == dropdims(sum(O[i], dims=4), dims=4) - end - end -end - -@testset "Identities are singletons" begin - @test IMPO === IdentityMPO() - @test IMPS === IdentityMPS() -end - -@testset "Identities have infinite length" begin - @test length(IMPS) == Inf - @test length(IMPO) == Inf -end - -@testset "Indexing identities returns trivial tensors" begin - @testset "Indexing IdentityMPS" begin - A = IMPS[42] - @test length(A) == 1 - @test ndims(A) == 3 - @test norm(A) == 1 - end - - @testset "Indexing IdentityMPO" begin - B = IMPO[666] - @test length(B) == 1 - @test ndims(B) == 4 - @test norm(B) == 1 - end -end \ No newline at end of file diff --git a/test/instances/128_001.txt b/test/instances/128_001.txt deleted file mode 100644 index 6e6454bd..00000000 --- a/test/instances/128_001.txt +++ /dev/null @@ -1,481 +0,0 @@ -# -1 1 0.200000 -2 2 0.146667 -3 3 -0.173333 -4 4 -0.200000 -5 5 0.013333 -6 6 0.040000 -7 7 0.013333 -8 8 0.120000 -9 9 -0.093333 -10 10 -0.013333 -11 11 0.120000 -12 12 0.173333 -13 13 0.093333 -14 14 0.040000 -15 15 -0.146667 -16 16 -0.146667 -17 17 -0.146667 -18 18 -0.013333 -19 19 0.173333 -20 20 -0.066667 -21 21 0.066667 -22 22 -0.120000 -23 23 -0.173333 -24 24 0.120000 -25 25 -0.146667 -26 26 -0.093333 -27 27 0.146667 -28 28 -0.173333 -29 29 -0.120000 -30 30 -0.146667 -31 31 0.120000 -32 32 -0.120000 -33 33 -0.200000 -34 34 -0.173333 -35 35 -0.066667 -36 36 -0.120000 -37 37 -0.040000 -38 38 0.173333 -39 39 0.040000 -40 40 0.120000 -41 41 -0.066667 -42 42 0.120000 -43 43 0.066667 -44 44 -0.173333 -45 45 0.120000 -46 46 0.120000 -47 47 -0.013333 -48 48 -0.120000 -49 49 -0.120000 -50 50 0.146667 -51 51 -0.066667 -52 52 0.066667 -53 53 0.146667 -54 54 0.120000 -55 55 -0.173333 -56 56 -0.146667 -57 57 -0.066667 -58 58 0.173333 -59 59 -0.173333 -60 60 -0.200000 -61 61 0.093333 -62 62 0.200000 -63 63 -0.200000 -64 64 -0.040000 -65 65 0.146667 -66 66 -0.040000 -67 67 0.120000 -68 68 -0.146667 -69 69 -0.120000 -70 70 -0.093333 -71 71 -0.013333 -72 72 -0.013333 -73 73 0.200000 -74 74 -0.173333 -75 75 -0.173333 -76 76 -0.200000 -77 77 0.066667 -78 78 0.200000 -79 79 -0.146667 -80 80 -0.173333 -81 81 -0.146667 -82 82 0.120000 -83 83 0.120000 -84 84 0.173333 -85 85 -0.013333 -86 86 -0.146667 -87 87 0.200000 -88 88 0.013333 -89 89 -0.173333 -90 90 0.200000 -91 91 0.173333 -92 92 -0.040000 -93 93 -0.120000 -94 94 -0.120000 -95 95 0.120000 -96 96 0.066667 -97 97 -0.066667 -98 98 -0.173333 -99 99 0.200000 -100 100 -0.066667 -101 101 -0.013333 -102 102 0.066667 -103 103 0.013333 -104 104 0.200000 -105 105 -0.120000 -106 106 0.120000 -107 107 -0.093333 -108 108 -0.013333 -109 109 -0.093333 -110 110 -0.173333 -111 111 -0.120000 -112 112 0.093333 -113 113 -0.120000 -114 114 -0.040000 -115 115 0.120000 -116 116 0.093333 -117 117 -0.146667 -118 118 -0.066667 -119 119 -0.066667 -120 120 -0.040000 -121 121 -0.200000 -122 122 -0.120000 -123 123 -0.093333 -124 124 -0.013333 -125 125 0.066667 -126 126 -0.200000 -127 127 0.173333 -128 128 -0.146667 -1 5 0.200000 -1 6 -0.333333 -1 7 0.866667 -1 8 -1.000000 -1 33 -0.200000 -2 5 -0.466667 -2 6 1.000000 -2 7 0.600000 -2 8 -0.066667 -2 34 4.333333 -3 5 0.466667 -3 6 -0.600000 -3 7 -0.866667 -3 8 -0.466667 -3 35 -0.066667 -4 5 0.600000 -4 6 -1.000000 -4 7 0.066667 -4 8 -3.666667 -4 36 -0.466667 -5 13 0.333333 -6 14 -0.733333 -7 15 1.000000 -8 16 -0.333333 -9 13 -0.600000 -9 14 0.866667 -9 15 -0.600000 -9 16 -0.466667 -9 41 -0.200000 -10 13 0.466667 -10 14 -0.600000 -10 15 0.733333 -10 16 -0.866667 -10 42 -1.000000 -11 13 0.200000 -11 14 0.333333 -11 15 1.000000 -11 16 -0.866667 -11 43 0.333333 -12 13 -0.866667 -12 14 0.066667 -12 15 0.466667 -12 16 0.600000 -12 44 -0.333333 -13 21 -0.466667 -14 22 0.466667 -15 23 -0.200000 -16 24 0.733333 -17 21 3.000000 -17 22 0.200000 -17 23 0.066667 -17 24 -0.200000 -17 49 -1.000000 -18 21 2.333333 -18 22 -0.866667 -18 23 2.333333 -18 24 1.000000 -18 50 0.866667 -19 21 -1.666667 -19 22 -0.866667 -19 23 -0.466667 -19 24 -1.000000 -19 51 -0.466667 -20 21 -0.333333 -20 22 -0.066667 -20 23 -0.866667 -20 24 -0.600000 -20 52 -1.000000 -21 29 -0.066667 -22 30 -0.066667 -23 31 0.466667 -24 32 1.000000 -25 29 0.200000 -25 30 0.733333 -25 31 -1.000000 -25 32 -0.066667 -25 57 0.466667 -26 29 -0.466667 -26 30 -0.733333 -26 31 0.733333 -26 32 -0.866667 -26 58 0.600000 -27 29 -0.066667 -27 30 -0.333333 -27 31 -1.000000 -27 32 -0.600000 -27 59 0.333333 -28 29 0.733333 -28 30 -0.066667 -28 31 -0.600000 -28 32 -0.733333 -28 60 0.333333 -33 37 0.733333 -33 38 4.333333 -33 39 0.600000 -33 40 -0.200000 -33 65 0.866667 -34 37 0.866667 -34 38 -1.000000 -34 39 -0.200000 -34 40 0.733333 -34 66 0.333333 -35 37 -0.333333 -35 38 -0.333333 -35 39 0.600000 -35 40 0.733333 -35 67 -0.600000 -36 37 0.466667 -36 38 0.733333 -36 39 0.200000 -36 40 -1.000000 -36 68 -0.333333 -37 45 0.333333 -38 46 -0.733333 -39 47 5.000000 -40 48 0.333333 -41 45 0.600000 -41 46 -0.333333 -41 47 -0.466667 -41 48 -4.333333 -41 73 -0.066667 -42 45 -0.600000 -42 46 -0.200000 -42 47 0.733333 -42 48 -0.466667 -42 74 0.866667 -43 45 -0.733333 -43 46 0.333333 -43 47 -2.333333 -43 48 0.200000 -43 75 0.333333 -44 45 0.866667 -44 46 -1.000000 -44 47 -0.866667 -44 48 -1.000000 -44 76 0.200000 -45 53 0.866667 -46 54 -0.200000 -47 55 0.333333 -48 56 -0.866667 -49 53 -0.466667 -49 54 -0.733333 -49 55 -0.066667 -49 56 -0.066667 -49 81 -0.600000 -50 53 -1.000000 -50 54 -1.000000 -50 55 -0.066667 -50 56 -0.600000 -50 82 3.000000 -51 53 1.000000 -51 54 0.200000 -51 55 0.200000 -51 56 0.733333 -51 83 -0.600000 -52 53 -0.733333 -52 54 -0.733333 -52 55 0.066667 -52 56 -0.733333 -52 84 0.733333 -53 61 0.733333 -54 62 0.733333 -55 63 -0.066667 -56 64 -2.333333 -57 61 5.000000 -57 62 0.333333 -57 63 -0.866667 -57 64 -0.466667 -57 89 1.000000 -58 61 -0.200000 -58 62 -0.200000 -58 63 0.066667 -58 64 0.466667 -58 90 -0.733333 -59 61 -0.733333 -59 62 -0.200000 -59 63 0.333333 -59 64 -0.733333 -59 91 -0.200000 -60 61 -0.333333 -60 62 -0.600000 -60 63 -0.200000 -60 64 5.000000 -60 92 0.866667 -65 69 -3.000000 -65 70 1.000000 -65 71 1.000000 -65 72 0.733333 -65 97 0.466667 -66 69 1.000000 -66 70 -0.333333 -66 71 -0.066667 -66 72 0.066667 -66 98 0.733333 -67 69 -0.733333 -67 70 0.600000 -67 71 -3.666667 -67 72 4.333333 -67 99 0.600000 -68 69 -0.866667 -68 70 0.466667 -68 71 -0.333333 -68 72 -0.600000 -68 100 0.200000 -69 77 -0.600000 -70 78 -0.600000 -71 79 0.866667 -72 80 -0.200000 -73 77 -0.200000 -73 78 -1.666667 -73 79 0.333333 -73 80 -0.466667 -73 105 0.733333 -74 77 -0.066667 -74 78 0.066667 -74 79 0.200000 -74 80 -0.200000 -74 106 0.466667 -75 77 0.866667 -75 78 0.333333 -75 79 -0.066667 -75 80 3.000000 -75 107 -1.000000 -76 77 1.666667 -76 78 1.000000 -76 79 -0.600000 -76 80 0.333333 -76 108 1.000000 -77 85 -0.866667 -78 86 0.866667 -79 87 0.466667 -80 88 0.733333 -81 85 -1.000000 -81 86 1.000000 -81 87 -0.466667 -81 88 3.666667 -81 113 -4.333333 -82 85 0.200000 -82 86 -0.200000 -82 87 0.866667 -82 88 -0.733333 -82 114 0.333333 -83 85 0.733333 -83 86 -0.200000 -83 87 0.066667 -83 88 0.333333 -83 115 -0.200000 -84 85 0.200000 -84 86 0.066667 -84 87 -0.866667 -84 88 -0.733333 -84 116 -0.333333 -85 93 0.333333 -86 94 -1.000000 -87 95 -0.866667 -88 96 -0.200000 -89 93 -0.066667 -89 94 0.600000 -89 95 -0.866667 -89 96 1.000000 -89 121 0.333333 -90 93 -0.466667 -90 94 0.733333 -90 95 1.000000 -90 96 -0.466667 -90 122 0.866667 -91 93 0.733333 -91 94 0.200000 -91 95 0.333333 -91 96 -0.733333 -91 123 -0.600000 -92 93 -0.600000 -92 94 -0.466667 -92 95 0.200000 -92 96 -0.733333 -92 124 0.600000 -97 101 -0.866667 -97 102 -0.333333 -97 103 -0.466667 -97 104 0.733333 -98 101 -2.333333 -98 102 -3.000000 -98 103 0.866667 -98 104 0.733333 -99 101 1.000000 -99 102 -0.866667 -99 103 0.733333 -99 104 -0.733333 -100 101 0.866667 -100 102 -0.066667 -100 103 -1.000000 -100 104 -0.200000 -101 109 0.466667 -102 110 0.600000 -103 111 0.066667 -104 112 0.600000 -105 109 -3.666667 -105 110 1.000000 -105 111 -1.000000 -105 112 0.600000 -106 109 0.466667 -106 110 0.733333 -106 111 0.600000 -106 112 0.866667 -107 109 3.666667 -107 110 -0.466667 -107 111 0.600000 -107 112 0.333333 -108 109 0.866667 -108 110 0.066667 -108 111 0.733333 -108 112 -0.733333 -109 117 0.333333 -110 118 -0.600000 -111 119 0.866667 -112 120 0.333333 -113 117 5.000000 -113 118 -0.866667 -113 119 -1.666667 -113 120 -0.600000 -114 117 1.000000 -114 118 0.333333 -114 119 0.333333 -114 120 -0.600000 -115 117 -0.466667 -115 118 -0.466667 -115 119 0.600000 -115 120 0.066667 -116 117 0.600000 -116 118 0.733333 -116 119 -0.600000 -116 120 0.333333 -117 125 -1.000000 -118 126 0.466667 -119 127 -0.466667 -120 128 0.466667 -121 125 -0.200000 -121 126 0.600000 -121 127 0.066667 -121 128 4.333333 -122 125 0.066667 -122 126 -0.600000 -122 127 1.000000 -122 128 0.333333 -123 125 0.466667 -123 126 -0.733333 -123 127 -0.066667 -123 128 0.600000 -124 125 -0.333333 -124 126 -0.466667 -124 127 -0.200000 -124 128 -0.866667 \ No newline at end of file diff --git a/test/instances/16_001.txt b/test/instances/16_001.txt deleted file mode 100644 index 35b36c65..00000000 --- a/test/instances/16_001.txt +++ /dev/null @@ -1,36 +0,0 @@ -# 4x4 -1 1 0.062500 -3 3 0.062500 -6 6 -0.062500 -7 7 0.062500 -8 8 0.031250 -9 9 -0.031250 -10 10 -0.031250 -12 12 -0.062500 -13 13 0.062500 -14 14 0.062500 -15 15 0.062500 -16 16 -0.031250 -1 2 0.187500 -1 5 -0.156250 -2 6 0.937500 -3 4 0.187500 -3 7 -0.031250 -4 8 -0.156250 -5 6 -1.000000 -5 9 0.156250 -6 7 0.187500 -6 10 0.250000 -7 8 0.093750 -7 11 0.156250 -8 12 0.187500 -9 10 0.093750 -9 13 -0.187500 -10 11 0.156250 -10 14 0.250000 -11 12 -0.156250 -11 15 -0.218750 -12 16 0.062500 -13 14 0.156250 -14 15 0.218750 -15 16 0.250000 \ No newline at end of file diff --git a/test/instances/4_001.txt b/test/instances/4_001.txt deleted file mode 100644 index bc184e31..00000000 --- a/test/instances/4_001.txt +++ /dev/null @@ -1,13 +0,0 @@ -# bias -1 1 0.1 -2 2 0.2 -3 3 0.3 -4 4 0.4 -# square -1 2 0.7 -1 3 0.4 -2 4 0.3 -3 4 0.5 -# diag -#1 4 0.6 -#2 3 0.4 diff --git a/test/instances/4_002.txt b/test/instances/4_002.txt deleted file mode 100644 index a1ee4093..00000000 --- a/test/instances/4_002.txt +++ /dev/null @@ -1,6 +0,0 @@ -# square -1 2 0.0 -1 3 0.0 -2 4 0.0 -3 4 0.0 - diff --git a/test/instances/9_001.txt b/test/instances/9_001.txt deleted file mode 100644 index 784a75bc..00000000 --- a/test/instances/9_001.txt +++ /dev/null @@ -1,22 +0,0 @@ -# i j v -1 2 0.1 -2 3 0.3 -4 5 0.7 -5 6 0.6 -7 8 0.5 -8 9 0.5 -1 4 0.7 -4 7 0.7 -2 5 0.2 -5 8 0.7 -3 6 0.3 -6 9 0.4 -1 1 0.1 -2 2 0.2 -3 3 0.3 -4 4 0.4 -5 5 0.5 -6 6 0.6 -7 7 0.7 -8 8 0.8 -9 9 0.9 diff --git a/test/instances/Egs.txt b/test/instances/Egs.txt deleted file mode 100644 index 3af03f42..00000000 --- a/test/instances/Egs.txt +++ /dev/null @@ -1,3 +0,0 @@ -# ins E_gs -16_001 -4.6875 -128_001 -210.9333333 diff --git a/test/instances/chimera_droplets/128power/001.txt b/test/instances/chimera_droplets/128power/001.txt deleted file mode 100755 index 6e6454bd..00000000 --- a/test/instances/chimera_droplets/128power/001.txt +++ /dev/null @@ -1,481 +0,0 @@ -# -1 1 0.200000 -2 2 0.146667 -3 3 -0.173333 -4 4 -0.200000 -5 5 0.013333 -6 6 0.040000 -7 7 0.013333 -8 8 0.120000 -9 9 -0.093333 -10 10 -0.013333 -11 11 0.120000 -12 12 0.173333 -13 13 0.093333 -14 14 0.040000 -15 15 -0.146667 -16 16 -0.146667 -17 17 -0.146667 -18 18 -0.013333 -19 19 0.173333 -20 20 -0.066667 -21 21 0.066667 -22 22 -0.120000 -23 23 -0.173333 -24 24 0.120000 -25 25 -0.146667 -26 26 -0.093333 -27 27 0.146667 -28 28 -0.173333 -29 29 -0.120000 -30 30 -0.146667 -31 31 0.120000 -32 32 -0.120000 -33 33 -0.200000 -34 34 -0.173333 -35 35 -0.066667 -36 36 -0.120000 -37 37 -0.040000 -38 38 0.173333 -39 39 0.040000 -40 40 0.120000 -41 41 -0.066667 -42 42 0.120000 -43 43 0.066667 -44 44 -0.173333 -45 45 0.120000 -46 46 0.120000 -47 47 -0.013333 -48 48 -0.120000 -49 49 -0.120000 -50 50 0.146667 -51 51 -0.066667 -52 52 0.066667 -53 53 0.146667 -54 54 0.120000 -55 55 -0.173333 -56 56 -0.146667 -57 57 -0.066667 -58 58 0.173333 -59 59 -0.173333 -60 60 -0.200000 -61 61 0.093333 -62 62 0.200000 -63 63 -0.200000 -64 64 -0.040000 -65 65 0.146667 -66 66 -0.040000 -67 67 0.120000 -68 68 -0.146667 -69 69 -0.120000 -70 70 -0.093333 -71 71 -0.013333 -72 72 -0.013333 -73 73 0.200000 -74 74 -0.173333 -75 75 -0.173333 -76 76 -0.200000 -77 77 0.066667 -78 78 0.200000 -79 79 -0.146667 -80 80 -0.173333 -81 81 -0.146667 -82 82 0.120000 -83 83 0.120000 -84 84 0.173333 -85 85 -0.013333 -86 86 -0.146667 -87 87 0.200000 -88 88 0.013333 -89 89 -0.173333 -90 90 0.200000 -91 91 0.173333 -92 92 -0.040000 -93 93 -0.120000 -94 94 -0.120000 -95 95 0.120000 -96 96 0.066667 -97 97 -0.066667 -98 98 -0.173333 -99 99 0.200000 -100 100 -0.066667 -101 101 -0.013333 -102 102 0.066667 -103 103 0.013333 -104 104 0.200000 -105 105 -0.120000 -106 106 0.120000 -107 107 -0.093333 -108 108 -0.013333 -109 109 -0.093333 -110 110 -0.173333 -111 111 -0.120000 -112 112 0.093333 -113 113 -0.120000 -114 114 -0.040000 -115 115 0.120000 -116 116 0.093333 -117 117 -0.146667 -118 118 -0.066667 -119 119 -0.066667 -120 120 -0.040000 -121 121 -0.200000 -122 122 -0.120000 -123 123 -0.093333 -124 124 -0.013333 -125 125 0.066667 -126 126 -0.200000 -127 127 0.173333 -128 128 -0.146667 -1 5 0.200000 -1 6 -0.333333 -1 7 0.866667 -1 8 -1.000000 -1 33 -0.200000 -2 5 -0.466667 -2 6 1.000000 -2 7 0.600000 -2 8 -0.066667 -2 34 4.333333 -3 5 0.466667 -3 6 -0.600000 -3 7 -0.866667 -3 8 -0.466667 -3 35 -0.066667 -4 5 0.600000 -4 6 -1.000000 -4 7 0.066667 -4 8 -3.666667 -4 36 -0.466667 -5 13 0.333333 -6 14 -0.733333 -7 15 1.000000 -8 16 -0.333333 -9 13 -0.600000 -9 14 0.866667 -9 15 -0.600000 -9 16 -0.466667 -9 41 -0.200000 -10 13 0.466667 -10 14 -0.600000 -10 15 0.733333 -10 16 -0.866667 -10 42 -1.000000 -11 13 0.200000 -11 14 0.333333 -11 15 1.000000 -11 16 -0.866667 -11 43 0.333333 -12 13 -0.866667 -12 14 0.066667 -12 15 0.466667 -12 16 0.600000 -12 44 -0.333333 -13 21 -0.466667 -14 22 0.466667 -15 23 -0.200000 -16 24 0.733333 -17 21 3.000000 -17 22 0.200000 -17 23 0.066667 -17 24 -0.200000 -17 49 -1.000000 -18 21 2.333333 -18 22 -0.866667 -18 23 2.333333 -18 24 1.000000 -18 50 0.866667 -19 21 -1.666667 -19 22 -0.866667 -19 23 -0.466667 -19 24 -1.000000 -19 51 -0.466667 -20 21 -0.333333 -20 22 -0.066667 -20 23 -0.866667 -20 24 -0.600000 -20 52 -1.000000 -21 29 -0.066667 -22 30 -0.066667 -23 31 0.466667 -24 32 1.000000 -25 29 0.200000 -25 30 0.733333 -25 31 -1.000000 -25 32 -0.066667 -25 57 0.466667 -26 29 -0.466667 -26 30 -0.733333 -26 31 0.733333 -26 32 -0.866667 -26 58 0.600000 -27 29 -0.066667 -27 30 -0.333333 -27 31 -1.000000 -27 32 -0.600000 -27 59 0.333333 -28 29 0.733333 -28 30 -0.066667 -28 31 -0.600000 -28 32 -0.733333 -28 60 0.333333 -33 37 0.733333 -33 38 4.333333 -33 39 0.600000 -33 40 -0.200000 -33 65 0.866667 -34 37 0.866667 -34 38 -1.000000 -34 39 -0.200000 -34 40 0.733333 -34 66 0.333333 -35 37 -0.333333 -35 38 -0.333333 -35 39 0.600000 -35 40 0.733333 -35 67 -0.600000 -36 37 0.466667 -36 38 0.733333 -36 39 0.200000 -36 40 -1.000000 -36 68 -0.333333 -37 45 0.333333 -38 46 -0.733333 -39 47 5.000000 -40 48 0.333333 -41 45 0.600000 -41 46 -0.333333 -41 47 -0.466667 -41 48 -4.333333 -41 73 -0.066667 -42 45 -0.600000 -42 46 -0.200000 -42 47 0.733333 -42 48 -0.466667 -42 74 0.866667 -43 45 -0.733333 -43 46 0.333333 -43 47 -2.333333 -43 48 0.200000 -43 75 0.333333 -44 45 0.866667 -44 46 -1.000000 -44 47 -0.866667 -44 48 -1.000000 -44 76 0.200000 -45 53 0.866667 -46 54 -0.200000 -47 55 0.333333 -48 56 -0.866667 -49 53 -0.466667 -49 54 -0.733333 -49 55 -0.066667 -49 56 -0.066667 -49 81 -0.600000 -50 53 -1.000000 -50 54 -1.000000 -50 55 -0.066667 -50 56 -0.600000 -50 82 3.000000 -51 53 1.000000 -51 54 0.200000 -51 55 0.200000 -51 56 0.733333 -51 83 -0.600000 -52 53 -0.733333 -52 54 -0.733333 -52 55 0.066667 -52 56 -0.733333 -52 84 0.733333 -53 61 0.733333 -54 62 0.733333 -55 63 -0.066667 -56 64 -2.333333 -57 61 5.000000 -57 62 0.333333 -57 63 -0.866667 -57 64 -0.466667 -57 89 1.000000 -58 61 -0.200000 -58 62 -0.200000 -58 63 0.066667 -58 64 0.466667 -58 90 -0.733333 -59 61 -0.733333 -59 62 -0.200000 -59 63 0.333333 -59 64 -0.733333 -59 91 -0.200000 -60 61 -0.333333 -60 62 -0.600000 -60 63 -0.200000 -60 64 5.000000 -60 92 0.866667 -65 69 -3.000000 -65 70 1.000000 -65 71 1.000000 -65 72 0.733333 -65 97 0.466667 -66 69 1.000000 -66 70 -0.333333 -66 71 -0.066667 -66 72 0.066667 -66 98 0.733333 -67 69 -0.733333 -67 70 0.600000 -67 71 -3.666667 -67 72 4.333333 -67 99 0.600000 -68 69 -0.866667 -68 70 0.466667 -68 71 -0.333333 -68 72 -0.600000 -68 100 0.200000 -69 77 -0.600000 -70 78 -0.600000 -71 79 0.866667 -72 80 -0.200000 -73 77 -0.200000 -73 78 -1.666667 -73 79 0.333333 -73 80 -0.466667 -73 105 0.733333 -74 77 -0.066667 -74 78 0.066667 -74 79 0.200000 -74 80 -0.200000 -74 106 0.466667 -75 77 0.866667 -75 78 0.333333 -75 79 -0.066667 -75 80 3.000000 -75 107 -1.000000 -76 77 1.666667 -76 78 1.000000 -76 79 -0.600000 -76 80 0.333333 -76 108 1.000000 -77 85 -0.866667 -78 86 0.866667 -79 87 0.466667 -80 88 0.733333 -81 85 -1.000000 -81 86 1.000000 -81 87 -0.466667 -81 88 3.666667 -81 113 -4.333333 -82 85 0.200000 -82 86 -0.200000 -82 87 0.866667 -82 88 -0.733333 -82 114 0.333333 -83 85 0.733333 -83 86 -0.200000 -83 87 0.066667 -83 88 0.333333 -83 115 -0.200000 -84 85 0.200000 -84 86 0.066667 -84 87 -0.866667 -84 88 -0.733333 -84 116 -0.333333 -85 93 0.333333 -86 94 -1.000000 -87 95 -0.866667 -88 96 -0.200000 -89 93 -0.066667 -89 94 0.600000 -89 95 -0.866667 -89 96 1.000000 -89 121 0.333333 -90 93 -0.466667 -90 94 0.733333 -90 95 1.000000 -90 96 -0.466667 -90 122 0.866667 -91 93 0.733333 -91 94 0.200000 -91 95 0.333333 -91 96 -0.733333 -91 123 -0.600000 -92 93 -0.600000 -92 94 -0.466667 -92 95 0.200000 -92 96 -0.733333 -92 124 0.600000 -97 101 -0.866667 -97 102 -0.333333 -97 103 -0.466667 -97 104 0.733333 -98 101 -2.333333 -98 102 -3.000000 -98 103 0.866667 -98 104 0.733333 -99 101 1.000000 -99 102 -0.866667 -99 103 0.733333 -99 104 -0.733333 -100 101 0.866667 -100 102 -0.066667 -100 103 -1.000000 -100 104 -0.200000 -101 109 0.466667 -102 110 0.600000 -103 111 0.066667 -104 112 0.600000 -105 109 -3.666667 -105 110 1.000000 -105 111 -1.000000 -105 112 0.600000 -106 109 0.466667 -106 110 0.733333 -106 111 0.600000 -106 112 0.866667 -107 109 3.666667 -107 110 -0.466667 -107 111 0.600000 -107 112 0.333333 -108 109 0.866667 -108 110 0.066667 -108 111 0.733333 -108 112 -0.733333 -109 117 0.333333 -110 118 -0.600000 -111 119 0.866667 -112 120 0.333333 -113 117 5.000000 -113 118 -0.866667 -113 119 -1.666667 -113 120 -0.600000 -114 117 1.000000 -114 118 0.333333 -114 119 0.333333 -114 120 -0.600000 -115 117 -0.466667 -115 118 -0.466667 -115 119 0.600000 -115 120 0.066667 -116 117 0.600000 -116 118 0.733333 -116 119 -0.600000 -116 120 0.333333 -117 125 -1.000000 -118 126 0.466667 -119 127 -0.466667 -120 128 0.466667 -121 125 -0.200000 -121 126 0.600000 -121 127 0.066667 -121 128 4.333333 -122 125 0.066667 -122 126 -0.600000 -122 127 1.000000 -122 128 0.333333 -123 125 0.466667 -123 126 -0.733333 -123 127 -0.066667 -123 128 0.600000 -124 125 -0.333333 -124 126 -0.466667 -124 127 -0.200000 -124 128 -0.866667 \ No newline at end of file diff --git a/test/instances/chimera_droplets/128power/groundstates_TN.txt b/test/instances/chimera_droplets/128power/groundstates_TN.txt deleted file mode 100644 index d7a9f9a0..00000000 --- a/test/instances/chimera_droplets/128power/groundstates_TN.txt +++ /dev/null @@ -1 +0,0 @@ -001.txt : -210.933333 1 0 1 1 0 1 1 1 0 1 1 0 0 1 0 1 1 1 0 0 0 0 0 0 1 0 1 1 0 0 1 1 1 1 0 1 0 0 1 1 0 1 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 1 1 1 1 1 0 0 0 1 0 0 0 1 0 1 0 0 1 1 0 0 1 0 0 1 1 1 0 1 0 1 1 0 0 0 1 1 1 0 0 0 1 1 0 0 1 1 1 1 0 0 1 0 1 0 0 0 1 1 1 0 0 0 0 1 0 1 1 1 0 1 diff --git a/test/instances/example.txt b/test/instances/example.txt deleted file mode 100644 index f6bbb1b0..00000000 --- a/test/instances/example.txt +++ /dev/null @@ -1,5 +0,0 @@ -1 1 0.1 -2 2 0.5 -1 4 -2.0 -4 2 1.0 -1 2 -0.3 diff --git a/test/instances/pathological/test_3_4_3.txt b/test/instances/pathological/test_3_4_3.txt deleted file mode 100644 index 5b7a2634..00000000 --- a/test/instances/pathological/test_3_4_3.txt +++ /dev/null @@ -1,35 +0,0 @@ -# i j Jij -1 4 1.0 -1 5 0.75 -1 6 -0.5 -4 7 0.5 -5 7 0.25 -6 8 -0.25 -6 9 0.5 -1 13 1.0 -5 16 -1.0 -6 16 1.0 -6 18 -0.5 -13 16 -0.75 -13 18 0.75 -18 28 0.75 -28 31 -0.75 -28 32 0.5 -28 33 0.25 -29 31 -0.25 -29 32 0.5 -29 33 0.25 -30 31 1.0 -30 32 -1.0 -30 33 0.5 -4 5 -0.5 -4 6 0.75 -5 6 0.5 -7 8 0.25 -7 9 -0.25 -16 18 0.5 -28 29 -0.5 -28 30 1.0 -29 30 -0.5 -6 6 0.05 -16 16 -0.1 \ No newline at end of file diff --git a/test/ising.jl b/test/ising.jl deleted file mode 100644 index b30852c2..00000000 --- a/test/ising.jl +++ /dev/null @@ -1,318 +0,0 @@ -using MetaGraphs -using LightGraphs -using GraphPlot -using CSV -using Test - -function _energy(config::Dict, couplings::Dict, cedges::Dict, n::Int) - eng = zeros(1,n) - for (i, j) ∈ keys(cedges) - for (k, l) ∈ values(cedges[i, j]) - for m ∈ 1:length(config[k]) - s = config[k][m] - r = config[l][m] - J = couplings[k, l] - if k == l - eng[m] += dot(s, J) - else - eng[m] += dot(s, J, r) - end - end - end - end - eng -end - -function _energy(ig::MetaGraph, config::Array) - s = size(config, 1) - eng = zeros(s) - for i ∈ 1:s - eng[i] = energy(config[i, :], ig) - end - eng -end - -@testset "Ising graph cannot be created" begin - - @testset "if input instance contains duplicate edges" begin - @test_throws ArgumentError ising_graph( - Dict( - (1, 1) => 2.0, - (1, 2) => 0.5, - (2, 1) => -1.0 - ) - ) - end -end - - -for (instance, source) ∈ ( - ("$(@__DIR__)/instances/example.txt", "file"), - ( - Dict( - (1, 1) => 0.1, - (2, 2) => 0.5, - (1, 4) => -2.0, - (4, 2) => 1.0, - (1, 2) => -0.3 - ), - "array" - ) -) -@testset "Ising graph created from $(source)" begin - expected_num_vertices = 3 - expected_biases = [0.1, 0.5, 0.0] - expected_couplings = Dict( - Edge(1, 2) => -0.3, - Edge(1, 3) => -2.0, - Edge(2, 3) => 1.0 - ) - expected_J_matrix = [ - [0 -0.3 -2.0]; - [0 0 0]; - [0 1.0 0]; - ] - - ig = ising_graph(instance) - - @testset "contains the same number vertices as original instance" begin - @test nv(ig) == expected_num_vertices - end - - @testset "has collection of edges comprising all interactions from instance" begin - # This test uses the fact that edges iterates in the lex ordering. - @test collect(edges(ig)) == [Edge(e...) for e in [(1, 2), (1, 3), (2, 3)]] - end - - @testset "stores biases both as property of vertices and its own property" begin - @test get_prop(ig, :h) == expected_biases - @test collect(map(v -> get_prop(ig, v, :h), vertices(ig))) == expected_biases - end - - @testset "stores couplings both as property of edges and its own property" begin - @test get_prop(ig, :J) == expected_J_matrix - @test all( - map(e -> expected_couplings[e] == get_prop(ig, e, :J), edges(ig)) - ) - end - - @testset "has default rank stored for each active vertex" begin - @test get_prop(ig, :rank) == Dict(1 => 2, 2 => 2, 3 => 2) - end -end -end - - -@testset "Ising graph created with additional parameters" begin - expected_biases = [-0.1, -0.5, 0.0] - expected_couplings = Dict( - Edge(1, 2) => 0.3, - Edge(1, 3) => 2.0, - Edge(2, 3) => -1.0 - ) - expected_J_matrix = [ - [0 0.3 2.0 ]; - [0 0 0]; - [0 -1.0 0]; - ] - - ig = ising_graph( - "$(@__DIR__)/instances/example.txt", - -1, - Dict(1 => 3, 4 => 4) - ) - - @testset "has rank overriden by rank_override dict" begin - # TODO: update default value of 2 once original implementation - # is also updated. - @test get_prop(ig, :rank) == Dict(1 => 3, 2 => 2, 3 => 4) - end - - @testset "has coefficients multiplied by given sign" begin - @test get_prop(ig, :h) == expected_biases - @test collect(map(v -> get_prop(ig, v, :h), vertices(ig))) == expected_biases - @test get_prop(ig, :J) == expected_J_matrix - @test all( - map(e -> expected_couplings[e] == get_prop(ig, e, :J), edges(ig)) - ) - end -end - - -@testset "Ising" begin - L = 4 - N = L^2 - instance = "$(@__DIR__)/instances/$(N)_001.txt" - - ig = ising_graph(instance) - - @test nv(ig) == N - - for i ∈ 1:N - @test has_vertex(ig, i) - end - - A = adjacency_matrix(ig) - - B = zeros(Int, N, N) - for i ∈ 1:N - nbrs = unique_neighbors(ig, i) - for j ∈ nbrs - B[i, j] = 1 - end - end - - @test B + B' == A - - gplot(ig, nodelabel=1:N) - - @testset "Naive brute force for +/-1" begin - k = 2^N - - sp = brute_force(ig, num_states=k) - - s = 5 - - @test sp.energies ≈ energy.(sp.states, Ref(ig)) - - β = rand(Float64) - ρ = gibbs_tensor(ig, β) - - @test size(ρ) == Tuple(fill(2, N)) - - r = exp.(-β .* sp.energies) - R = r ./ sum(r) - - @test sum(R) ≈ 1 - @test sum(ρ) ≈ 1 - - @test [ ρ[idx.(σ)...] for σ ∈ sp.states ] ≈ R - end - - @testset "Naive brute force for general spins" begin - L = 4 - instance = "$(@__DIR__)/instances/$(L)_001.txt" - - ig = ising_graph(instance) - - set_prop!(ig, :rank, [3,2,5,4]) - rank = get_prop(ig, :rank) - - all = prod(rank) - sp = brute_force(ig, num_states=all) - - β = rand(Float64) - ρ = exp.(-β .* sp.energies) - - ϱ = ρ ./ sum(ρ) - ϱ̃ = gibbs_tensor(ig, β) - - @test [ ϱ̃[idx.(σ)...] for σ ∈ sp.states ] ≈ ϱ - end - - @testset "Reading from Dict" begin - instance_dict = Dict() - ising = CSV.File(instance, types=[Int, Int, Float64], header=0, comment = "#") - - for (i, j, v) ∈ ising - push!(instance_dict, (i, j) => v) - end - - ig = ising_graph(instance) - ig_dict = ising_graph(instance_dict) - - @test gibbs_tensor(ig) ≈ gibbs_tensor(ig_dict) - end -end - - -@testset "Ground state energy for pathological instance " begin -m = 3 -n = 4 -t = 3 - -β = 1 - -instance = "$(@__DIR__)/instances/pathological/test_$(m)_$(n)_$(t).txt" - -ising = CSV.File(instance, types=[Int, Int, Float64], header=0, comment = "#") -ig = ising_graph(instance) - -conf = [ - -1 1 1 -1 -1 -1 1 1 1 -1 1 1 -1 1 -1 1; - -1 1 1 -1 -1 -1 1 1 1 -1 1 1 -1 1 -1 -1; - -1 1 1 -1 -1 1 1 1 1 -1 1 1 -1 1 -1 1; - -1 1 1 -1 -1 1 1 1 1 -1 1 1 -1 1 -1 -1] - -eng = _energy(ig, conf) - -couplings = Dict() -for (i, j, v) ∈ ising - push!(couplings, (i, j) => v) -end - -cedges = Dict() -push!(cedges, (1, 2) => [(1, 4), (1, 5), (1, 6)]) -push!(cedges, (1, 5) => [(1, 13)]) - -push!(cedges, (2, 3) => [(4, 7), (5, 7), (6, 8), (6, 9)]) -push!(cedges, (2, 6) => [(6, 16), (6, 18), (5, 16)]) - -push!(cedges, (5, 6) => [(13, 16), (13, 18)]) - -push!(cedges, (6, 10) => [(18, 28)]) -push!(cedges, (10, 11) => [(28, 31), (28, 32), (28, 33), (29, 31), (29, 32), (29, 33), (30, 31), (30, 32), (30, 33)]) - -push!(cedges, (2, 2) => [(4, 5), (4, 6), (5, 6), (6, 6)]) -push!(cedges, (3, 3) => [(7, 8), (7, 9)]) -push!(cedges, (6, 6) => [(16, 18), (16, 16)]) -push!(cedges, (10, 10) => [(28, 29), (28, 30), (29, 30)]) - -config = Dict() -push!(config, 1 => [-1, -1, -1, -1]) -push!(config, 2 => [0, 0, 0, 0]) -push!(config, 3 => [0, 0, 0, 0]) -push!(config, 4 => [1, 1, 1, 1]) -push!(config, 5 => [1, 1, 1, 1]) -push!(config, 6 => [-1, -1, -1, -1]) -push!(config, 7 => [-1, -1, -1, -1]) -push!(config, 8 => [-1, -1, 1, 1]) -push!(config, 9 => [1, 1, 1, 1]) -push!(config, 10 => [0, 0, 0, 0]) -push!(config, 11 => [0, 0, 0, 0]) -push!(config, 12 => [0, 0, 0, 0]) -push!(config, 13 => [1, 1, 1, 1]) -push!(config, 14 => [0, 0, 0, 0]) -push!(config, 15 => [0, 0, 0, 0]) -push!(config, 16 => [1, 1, 1, 1]) -push!(config, 17 => [0, 0, 0, 0]) -push!(config, 18 => [-1, -1, -1, -1]) -push!(config, 19 => [0, 0, 0, 0]) -push!(config, 20 => [0, 0, 0, 0]) -push!(config, 21 => [0, 0, 0, 0]) -push!(config, 22 => [0, 0, 0, 0]) -push!(config, 23 => [0, 0, 0, 0]) -push!(config, 24 => [0, 0, 0, 0]) -push!(config, 25 => [0, 0, 0, 0]) -push!(config, 26 => [0, 0, 0, 0]) -push!(config, 27 => [0, 0, 0, 0]) -push!(config, 28 => [1, 1, 1, 1]) -push!(config, 29 => [1, 1, 1, 1]) -push!(config, 30 => [-1, -1, -1, -1]) -push!(config, 31 => [1, 1, 1, 1]) -push!(config, 32 => [-1, -1, -1, -1]) -push!(config, 33 => [1,-1, 1, -1]) -push!(config, 34 => [0, 0, 0, 0]) -push!(config, 35 => [0, 0, 0, 0]) -push!(config, 36 => [0, 0, 0, 0]) - -num_config = length(config[1]) -exact_energy = _energy(config, couplings, cedges, num_config) - -low_energies = [-16.4, -16.4, -16.4, -16.4, -16.1, -16.1, -16.1, -16.1, -15.9, -15.9, -15.9, -15.9, -15.9, -15.9, -15.6, -15.6, -15.6, -15.6, -15.6, -15.6, -15.4, -15.4] - -for i ∈ 1:num_config - @test exact_energy[i] == low_energies[i] == eng[i] -end - -end diff --git a/test/runtests.jl b/test/runtests.jl index 3f629dc1..e9a19dbb 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,20 +1,4 @@ -using CUDA -using SpinGlassPEPS -using LinearAlgebra -using TensorOperations -using TensorCast -using LightGraphs -using MetaGraphs -using Random -using Logging -using Statistics -using NPZ - -disable_logging(LogLevel(1)) - -using Test - -include("test_helpers.jl") +using Test, CUDA, SpinGlassPEPS my_tests = [] if CUDA.functional() && CUDA.has_cutensor() && false @@ -29,23 +13,6 @@ if CUDA.functional() && CUDA.has_cutensor() && false ) end -my_tests = [] -include("test_helpers.jl") -push!(my_tests, - "base.jl", - "utils.jl", - "contractions.jl", - "compressions.jl", - "identities.jl", - "ising.jl", - "MPS_search.jl", - "factor.jl", - "PEPS.jl", - "contract.jl", - "search.jl", - "search_2.jl" -) - for my_test in my_tests include(my_test) -end +end \ No newline at end of file diff --git a/test/search.jl b/test/search.jl deleted file mode 100644 index ba6718bb..00000000 --- a/test/search.jl +++ /dev/null @@ -1,136 +0,0 @@ -using LinearAlgebra -using MetaGraphs -using LightGraphs -using GraphPlot -using CSV - -@testset "Simplest possible system of two spins" begin - # - # ----------------- Ising model ------------------ - # - # E = -1.0 * s1 * s2 + 0.5 * s1 + 0.75 * s2 - # - # states -> [[-1, -1], [1, 1], [1, -1], [-1, 1]] - # energies -> [-2.25, 0.25, 0.75, 1.25] - # - # ------------------------------------------------- - # Grid - # A1 | A2 - # | - # 1 - | - 2 - # ------------------------------------------------- - - # Model's parameters - J12 = -1.0 - h1 = 0.5 - h2 = 0.75 - - # dict to be read - D = Dict((1, 2) => J12, - (1, 1) => h1, - (2, 2) => h2, - ) - - # control parameters - m, n = 1, 2 - L = 2 - β = 1. - num_states = 4 - - # read in pure Ising - ig = ising_graph(D) - - # construct factor graph with no approx - fg = factor_graph( - ig, - Dict(1 => 2, 2 => 2), - energy = energy, - spectrum = full_spectrum, - cluster_assignment_rule = Dict(1 => 1, 2 => 2), # treat it as a grid with 1 spin cells - ) - - # set parameters to contract exactely - control_params = Dict( - "bond_dim" => typemax(Int), - "var_tol" => 1E-8, - "sweeps" => 4. - ) - - # get BF results for comparison - exact_spectrum = brute_force(ig; num_states=num_states) - ϱ = gibbs_tensor(ig, β) - - # split on the bond - p1, e, p2 = get_prop.(Ref(fg), 1, 2, (:pl, :en, :pr)) - - @testset "has correct energy on the bond" begin - en = [ J12 * σ * η for σ ∈ [-1, 1], η ∈ [-1, 1]] - @test en ≈ p1 * (e * p2) - @test p1 ≈ p2 ≈ I - end - - for origin ∈ (:NW, :SW, :WS, :WN, :NE, :EN, :SE, :ES) - peps = PEPSNetwork(m, n, fg, β, origin, control_params) - - @testset "has properly built PEPS tensors given origin at $(origin)" begin - - # horizontal alignment - 1 row, 2 columns - if peps.i_max == 1 && peps.j_max == 2 - @test origin ∈ (:NW, :SW, :SE, :NE) - - l, k = peps.map[1, 1], peps.map[1, 2] - - v1 = [exp(-β * D[l, l] * σ) for σ ∈ [-1, 1]] - v2 = [exp(-β * D[k, k] * σ) for σ ∈ [-1, 1]] - - @cast A[_, _, r, _, σ] |= v1[σ] * p1[σ, r] - en = e * p2 .- minimum(e) - @cast B[l, _, _, _, σ] |= v2[σ] * exp.(-β * en)[l, σ] - - @reduce ρ[σ, η] := sum(l) A[1, 1, l, 1, σ] * B[l, 1, 1, 1, η] - if l == 2 ρ = ρ' end - - R = PEPSRow(peps, 1) - @test [R[1], R[2]] ≈ [A, B] - - # vertical alignment - 1 column, 2 rows - elseif peps.i_max == 2 && peps.j_max == 1 - @test origin ∈ (:WN, :WS, :ES, :EN) - - l, k = peps.map[1, 1], peps.map[2, 1] - - v1 = [exp(-β * D[l, l] * σ) for σ ∈ [-1, 1]] - v2 = [exp(-β * D[k, k] * σ) for σ ∈ [-1, 1]] - - @cast A[_, _, _, d, σ] |= v1[σ] * p1[σ, d] - en = e * p2 .- minimum(e) - @cast B[_, u, _, _, σ] |= v2[σ] * exp.(-β * en)[u, σ] - - @reduce ρ[σ, η] := sum(u) A[1, 1, 1, u, σ] * B[1, u, 1, 1, η] - if l == 2 ρ = ρ' end - - @test PEPSRow(peps, 1)[1] ≈ A - @test PEPSRow(peps, 2)[1] ≈ B - end - - @testset "which produces correct Gibbs state" begin - @test ϱ ≈ ρ / sum(ρ) - end - end - - # solve the problem using B & B - sol = low_energy_spectrum(peps, num_states) - - @testset "has correct spectrum given the origin at $(origin)" begin - for (σ, η) ∈ zip(exact_spectrum.states, sol.states) - for i ∈ 1:peps.i_max, j ∈ 1:peps.j_max - v = j + peps.j_max * (i - 1) - # 1 --> -1 and 2 --> 1 - @test (η[v] == 1 ? -1 : 1) == σ[v] - end - end - @test sol.energies ≈ exact_spectrum.energies - @test sol.largest_discarded_probability === -Inf - end - end -end diff --git a/test/search_2.jl b/test/search_2.jl deleted file mode 100644 index f5ea0e3c..00000000 --- a/test/search_2.jl +++ /dev/null @@ -1,96 +0,0 @@ -using MetaGraphs -using LightGraphs -using GraphPlot -using CSV - -@testset "Pathological instance" begin - m = 3 - n = 4 - t = 3 - - β = 1. - - L = n * m * t - num_states = 22 - - # energies - exact_energies = - [ - -16.4, -16.4, -16.4, -16.4, -16.1, -16.1, -16.1, -16.1, -15.9, - -15.9, -15.9, -15.9, -15.9, -15.9, -15.6, -15.6, -15.6, -15.6, - -15.6, -15.6, -15.4, -15.4 - ] - - # degenerate fg solutions - exact_states = - [ # E =-16.4 - [ - [1, 4, 5, 1, 2, 2, 1, 1, 1, 4, 2, 1], [1, 4, 7, 1, 2, 2, 1, 1, 1, 4, 2, 1], - [1, 4, 5, 1, 2, 2, 1, 1, 1, 4, 6, 1], [1, 4, 7, 1, 2, 2, 1, 1, 1, 4, 6, 1] - ], - # E =-16.1 - [ - [2, 5, 4, 1, 1, 3, 1, 1, 1, 5, 7, 1], [2, 5, 2, 1, 1, 3, 1, 1, 1, 5, 3, 1], - [2, 5, 4, 1, 1, 3, 1, 1, 1, 5, 3, 1], [2, 5, 2, 1, 1, 3, 1, 1, 1, 5, 7, 1] - ], - # E = -15.9 - [ - [1, 4, 1, 1, 2, 2, 1, 1, 1, 4, 2, 1], [1, 4, 3, 1, 2, 2, 1, 1, 1, 4, 2, 1], - [1, 4, 6, 1, 2, 2, 1, 1, 1, 4, 2, 1], [1, 4, 3, 1, 2, 2, 1, 1, 1, 4, 6, 1], - [1, 4, 1, 1, 2, 2, 1, 1, 1, 4, 6, 1], [1, 4, 6, 1, 2, 2, 1, 1, 1, 4, 6, 1] - ], - # E = -15.6 - [ - [2, 5, 3, 1, 1, 3, 1, 1, 1, 5, 3, 1], [2, 5, 3, 1, 1, 3, 1, 1, 1, 5, 7, 1], - [2, 5, 8, 1, 1, 3, 1, 1, 1, 5, 3, 1], [2, 5, 6, 1, 1, 3, 1, 1, 1, 5, 7, 1], - [2, 5, 6, 1, 1, 3, 1, 1, 1, 5, 3, 1], [2, 5, 8, 1, 1, 3, 1, 1, 1, 5, 7, 1] - ], - # E = -15.4 - [ - [1, 4, 7, 1, 2, 2, 1, 1, 1, 2, 6, 1], [1, 4, 5, 1, 2, 2, 1, 1, 1, 2, 6, 1] - ], - ] - - deg = Dict( - 1 => 1, 2 => 1, 3 => 1, 4 => 1, - # - 5 => 2, 6 => 2, 7 => 2, 8 => 2, - # - 9 => 3, 10 => 3, 11 => 3, 12 => 3, 13 => 3, 14 => 3, - # - 15 => 4, 16 => 4, 17 => 4, 18 => 4, 19 => 4, 20 => 4, - # - 21 => 5, 22 => 5, - ) - - control_params = Dict( - "bond_dim" => typemax(Int), - "var_tol" => 1E-8, - "sweeps" => 4. - ) - - instance = "$(@__DIR__)/instances/pathological/test_$(m)_$(n)_$(t).txt" - - ig = ising_graph(instance) - - fg = factor_graph( - ig, - energy=energy, - spectrum=full_spectrum, - cluster_assignment_rule=super_square_lattice((m, n, t)) - ) - - for origin ∈ (:NW, :SW, :WS, :WN, :NE, :EN, :SE, :ES) - peps = PEPSNetwork(m, n, fg, β, origin, control_params) - - # solve the problem using B & B - sol = low_energy_spectrum(peps, num_states) - - @testset "has correct spectrum given the origin at $(origin)" begin - @test sol.energies ≈ exact_energies - for (i, σ) ∈ enumerate(sol.states) - @test σ ∈ exact_states[deg[i]] - end - end - end -end diff --git a/test/test_helpers.jl b/test/test_helpers.jl deleted file mode 100644 index b3406a8c..00000000 --- a/test/test_helpers.jl +++ /dev/null @@ -1,141 +0,0 @@ -function proj(state, dims::Union{Vector, NTuple}) - P = Matrix{Float64}[] - for (σ, r) ∈ zip(state, dims) - v = zeros(r) - v[idx(σ)...] = 1. - push!(P, v * v') - end - P -end - -function tensor(ψ::AbstractMPS, state::State) - C = I - for (A, σ) ∈ zip(ψ, state) - C *= A[:, idx(σ), :] - end - tr(C) -end - -function tensor(ψ::MPS) - dims = rank(ψ) - Θ = Array{eltype(ψ)}(undef, dims) - - for σ ∈ all_states(dims) - Θ[idx.(σ)...] = tensor(ψ, σ) - end - Θ -end - -#removes bonds that do not fit to the grid, testing function -function fullM2grid!(M::Matrix{Float64}, s::Tuple{Int, Int}) - s1 = s[1] - s2 = s[2] - pairs = Vector{Int}[] - for i ∈ 1:s1*s2 - if (i%s2 > 0 && i < s1*s2) - push!(pairs, [i, i+1]) - end - if i <= s2*(s1-1) - push!(pairs, [i, i+s2]) - end - end - - for k ∈ CartesianIndices(size(M)) - i1 = [k[1], k[2]] - i2 = [k[2], k[1]] - if !(i1 ∈ pairs) && !(i2 ∈ pairs) && (k[1] != k[2]) - M[i1...] = M[i2...] = 0. - end - end -end - - -function make_interactions_case1() - L = 9 - - D = Dict{Tuple{Int64,Int64},Float64}() - push!( - D, - (1,1) => 1.0, - (2,2) => -2.0, - (3,3) => 4.0, - (4,4) => 0.0, - (5,5) => 1.5, - (6,6) => 0.1, - (7,7) => 0.7, - (8,8) => -0.16, - (9,9) => 0.66, - - (1, 2) => -1.0, - (1, 4) => -3, - (2, 3) => -3.0, - (2, 5) => -2.0, - (3,6) => 3.0, - (4,5) => 1.0, - (4,7) => -0.02, - (5,6) => -0.5, - (5,8) => 1.0, - (6,9) => -1.04, - (7,8) => 1.7, - (8,9) => -0.1) - - - ising_graph(D)#, ising_graph(D, L) -end - - -function make_interactions_case2(T::Type = Float64) - f = 1 - f1 = 1 - L = 16 - D = Dict{Tuple{Int64,Int64},T}() - push!( - D, - (1, 1) => T(-2.8), - (2, 2) => T(2.7), - (3, 3) => T(-2.6), - (4, 4) => T(2.5), - (5, 5) => T(-2.4), - (6, 6) => T(2.3), - (7, 7) => T(-2.2), - (8, 8) => T(2.1), - (9, 9) => T(-2.0), - (10, 10) => T(1.9), - (11, 11) => T(-1.8), - (12, 12) => T(1.70), - (13, 13) => T(-1.6), - (14, 14) => T(1.5), - (15, 15) => T(-1.4), - (16, 16) => T(1.3), - - (1, 2) => T(0.30), - (1, 5) => T(0.2), - (2, 3) => T(0.255), - (2, 6) => T(0.21), - (3, 4) => T(0.222), - (3, 7) => T(0.213), - - (4, 8) => T(0.2), - (5, 6) => T(0.15), - (5, 9) => T(0.211), - (6, 7) => T(0.2), - (6, 10) => T(0.15), - (7, 8) => T(0.11), - (7, 11) => T(0.35), - (8, 12) => T(0.19), - (9, 10) => T(0.222), - (9, 13) => T(0.15), - (10, 11) => T(0.28), - (10, 14) => T(0.21), - (11, 12) => T(0.19), - (11, 15) => T(0.18), - (12, 16) => T(0.27), - (13, 14) => T(0.32), - (14, 15) => T(0.19), - (15, 16) => T(0.21) - ) - - ising_graph(D) -end - -enum(vec) = Dict(v => i for (i, v) ∈ enumerate(vec)) diff --git a/test/utils.jl b/test/utils.jl deleted file mode 100644 index e222343f..00000000 --- a/test/utils.jl +++ /dev/null @@ -1,9 +0,0 @@ -@testset "HadamardMPS" begin - rank = (2, 3, 4) - T = Float64 - ψ = HadamardMPS(T, rank) - - @testset "Has correct size" begin - @test size(ψ) == (length(rank), ) - end -end