Ian Jauslin
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Jauslin <ian@jauslin.org>2021-10-04 11:12:34 -0400
committerIan Jauslin <ian@jauslin.org>2021-10-04 11:22:07 -0400
commite72af82c3ed16b81cdb5043c58abbdbb3cf02102 (patch)
tree2d2a4bf7a7e4be1e1d69dce37ff5ff37a83ff375
Initial commitv0.3
-rw-r--r--LICENSE202
-rw-r--r--NOTICE4
-rw-r--r--README102
-rw-r--r--doc/Makefile54
-rw-r--r--doc/bibliography/bibliography.tex13
-rw-r--r--doc/libs/code.sty43
-rw-r--r--doc/libs/dlmf.sty55
-rw-r--r--doc/libs/ian.cls682
-rw-r--r--doc/libs/iantheo.sty176
-rw-r--r--doc/libs/largearray.sty33
-rw-r--r--doc/libs/point.sty128
-rw-r--r--doc/simplesolv-doc.tex3679
-rw-r--r--src/anyeq.jl949
-rw-r--r--src/chebyshev.jl279
-rw-r--r--src/easyeq.jl411
-rw-r--r--src/integration.jl58
-rw-r--r--src/interpolation.jl108
-rw-r--r--src/main.jl443
-rw-r--r--src/potentials.jl84
-rw-r--r--src/print.jl52
-rw-r--r--src/simpleq-Kv.jl119
-rw-r--r--src/simpleq-hardcore.jl573
-rw-r--r--src/simpleq-iteration.jl94
-rw-r--r--src/tools.jl49
24 files changed, 8390 insertions, 0 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+ 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/NOTICE b/NOTICE
new file mode 100644
index 0000000..216093f
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,4 @@
+simplesolv:
+Licensed under the Apache 2.0 License (see LICENSE for details)
+Copyright Ian Jauslin 2021
+
diff --git a/README b/README
new file mode 100644
index 0000000..ffc52d5
--- /dev/null
+++ b/README
@@ -0,0 +1,102 @@
+simplesolv is a program to compute the solution of the Simplified approach to
+the Bose gas.
+
+It is written in julia, and requires the julia interpreter to run.
+
+The code is available in the 'src' directory.
+
+The LaTeX source code for the documentation is located in the 'doc' directory.
+A pdf file is available in the source tarball, as well as at
+ http://ian.jauslin.org/software/simplesolv/simplesolv-doc.pdf
+The documentation basic usage examples, an extensive reference of all commands,
+and detailed descriptions of the numerical algorithms used.
+
+Any questions, concerns, or bug reports should be addressed to Ian Jauslin at
+ ian.jauslin@rutgers.edu
+
+simplesolv was written by Ian Jauslin, and is released under the Apache 2.0
+license. It is based on work done in collaboration with
+ Eric A. Carlen
+ Markus Holzmann
+ Elliott H. Lieb
+published in the following papers:
+ * E.A. Carlen, I. Jauslin, E.H. Lieb - Analysis of a simple equation for the
+ ground state energy of the Bose gas, Pure and Applied Analysis, volume 2,
+ issue 3, pages 659-684, 2020,
+ https://doi.org/10.2140/paa.2020.2.659
+ https://arxiv.org/abs/1912.04987
+ http://ian.jauslin.org/publications/19cjl
+
+ * E.A. Carlen, I. Jauslin, E.H. Lieb - Analysis of a simple equation for the
+ ground state energy of the Bose gas II: Monotonicity, Convexity and
+ Condensate Fraction, to appear in the SIAM Journal on Mathematical Analysis
+ https://arxiv.org/abs/2010.13882
+ http://ian.jauslin.org/publications/20cjl
+
+ * E.A. Carlen, M. Holzmann, I. Jauslin, E.H. Lieb - Simplified approach to
+ the repulsive Bose gas from low to high densities and its numerical
+ accuracy, Physical Review A, volume 103, issue 5, number 053309, 2021
+ https://doi.org/10.1103/PhysRevA.103.053309
+ https://arxiv.org/abs/2011.10869
+ http://ian.jauslin.org/publications/20chjl
+
+
+
+Dependencies:
+
+ * julia interpreter
+ Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors: https://github.com/JuliaLang/julia/contributors
+ https://julialang.org/
+ MIT and GNU GPLv2 Licenses
+ * julia packages:
+ FastGaussQuadrature
+ Alex Townsend
+ https://github.com/JuliaApproximation/FastGaussQuadrature.jl
+ MIT license
+ Polynomials
+ Jameson Nash and others
+ https://github.com/JuliaMath/Polynomials.jl
+ MIT license
+ SpecialFunctions
+ Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and others
+ https://github.com/JuliaMath/SpecialFunctions.jl/
+ MIT License
+
+ to typeset the documentation:
+ * pdftex
+ pdfTeX team, TeX Live Team, Hàn Thế Thành
+ http://tug.org/applications/pdftex/
+ GNU GPL
+ * latex
+ LaTeX3 Project
+ https://www.latex-project.org/
+ LaTeX Project Public License 1.3c
+ * LaTeX packages:
+ color
+ David Carlisle, LaTeX3 Project
+ https://ctan.org/pkg/color
+ LaTeX Project Public License 1.3c
+ marginnote
+ Markus Kohm
+ https://komascript.de/marginnote
+ LaTeX Project Public License 1.3c
+ amsfonts
+ American Mathematical Society
+ http://www.ams.org/tex/amsfonts.html
+ SIL Open Font Licence
+ hyperref
+ Sebastian Rahtz, Heiko Oberdiek, LaTeX3 Project
+ https://github.com/latex3/hyperref
+ LaTeX Project Public License 1.3
+ array
+ LaTeX project, Frank Mittelbach
+ https://ctan.org/pkg/array
+ LaTeX Project Public License 1.3
+ doublestroke
+ Olaf Kummer
+ https://ctan.org/pkg/doublestroke
+ Custom Free license
+ * optionally: GNU Make
+ Richard Stallman, Roland McGrath, Paul Smith
+ https://www.gnu.org/software/make/
+ GNU GPLv3
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 0000000..4b58b3c
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,54 @@
+## Copyright 2021 Ian Jauslin
+##
+## 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.
+
+PROJECTNAME=$(basename $(wildcard *.tex))
+LIBS=$(notdir $(wildcard libs/*))
+
+PDFS=$(addsuffix .pdf, $(PROJECTNAME))
+SYNCTEXS=$(addsuffix .synctex.gz, $(PROJECTNAME))
+
+all: $(PROJECTNAME)
+
+$(PROJECTNAME): $(LIBS)
+ pdflatex -file-line-error $@.tex
+ pdflatex -file-line-error $@.tex
+ pdflatex -synctex=1 $@.tex
+
+$(PROJECTNAME).aux: $(LIBS)
+ pdflatex -file-line-error -draftmode $(PROJECTNAME).tex
+
+
+$(SYNCTEXS): $(LIBS)
+ pdflatex -synctex=1 $(patsubst %.synctex.gz, %.tex, $@)
+
+
+libs: $(LIBS)
+
+$(LIBS):
+ ln -fs libs/$@ ./
+
+
+clean-aux:
+ rm -f $(addsuffix .aux, $(PROJECTNAME))
+ rm -f $(addsuffix .log, $(PROJECTNAME))
+ rm -f $(addsuffix .out, $(PROJECTNAME))
+ rm -f $(addsuffix .toc, $(PROJECTNAME))
+
+clean-libs:
+ rm -f $(LIBS)
+
+clean-tex:
+ rm -f $(PDFS) $(SYNCTEXS)
+
+clean: clean-aux clean-tex clean-libs
diff --git a/doc/bibliography/bibliography.tex b/doc/bibliography/bibliography.tex
new file mode 100644
index 0000000..53454da
--- /dev/null
+++ b/doc/bibliography/bibliography.tex
@@ -0,0 +1,13 @@
+\bibitem[CHe21]{CHe21}E.A. Carlen, M. Holzmann, I. Jauslin, E.H. Lieb - {\it Simplified approach to the repulsive Bose gas from low to high densities and its numerical accuracy}, Physical Review A, volume~\-103, issue~\-5, number~\-053309, 2021,\par\penalty10000
+doi:{\tt\color{blue}\href{http://dx.doi.org/10.1103/PhysRevA.103.053309}{10.1103/PhysRevA.103.053309}}, arxiv:{\tt\color{blue}\href{http://arxiv.org/abs/2011.10869}{2011.10869}}.\par\medskip
+
+\bibitem[CJL20]{CJL20}E.A. Carlen, I. Jauslin, E.H. Lieb - {\it Analysis of a simple equation for the ground state energy of the Bose gas}, Pure and Applied Analysis, volume~\-2, issue~\-3, pages~\-659-684, 2020,\par\penalty10000
+doi:{\tt\color{blue}\href{http://dx.doi.org/10.2140/paa.2020.2.659}{10.2140/paa.2020.2.659}}, arxiv:{\tt\color{blue}\href{http://arxiv.org/abs/1912.04987}{1912.04987}}.\par\medskip
+
+\bibitem[CJL20b]{CJL20b}E.A. Carlen, I. Jauslin, E.H. Lieb - {\it Analysis of a simple equation for the ground state of the Bose gas II: Monotonicity, Convexity and Condensate Fraction}, 2020, to appear in the SIAM journal of Mathematical Analysis,\par\penalty10000
+arxiv:{\tt\color{blue}\href{http://arxiv.org/abs/2010.13882}{2010.13882}}.\par\medskip
+
+\bibitem[DLMF]{DLMF1.1.3}F.W.J. Olver, A.B. Olde Daalhuis, D.W. Lozier, B.I. Schneider, R.F. Boisvert, C.W. Clark, B.R. Miller, B.V. Saunders, H.S. Cohl, M.A. McClain (editors) - {\it NIST Digital Library of Mathematical Functions}, Release~\-1.1.3 of~\-2021-09-15, 2021.\par\medskip
+
+\bibitem[Ta87]{Ta87}Y. Taguchi - {\it Fourier coefficients of periodic functions of Gevrey classes and ultradistributions}, Yokohama Mathematical Journal, volume~\-35, pages~\-51-60, 1987.\par\medskip
+
diff --git a/doc/libs/code.sty b/doc/libs/code.sty
new file mode 100644
index 0000000..d4f4070
--- /dev/null
+++ b/doc/libs/code.sty
@@ -0,0 +1,43 @@
+%% Copyright 2021 Ian Jauslin
+%%
+%% 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.
+
+%%
+%% Code package:
+%% commands to typeset code
+%%
+
+%% TeX format
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+
+%% package name
+\ProvidesPackage{code}[2021/03/15]
+
+%% code environment
+\def\code{
+ \par
+ \leftskip10pt
+ \bigskip
+ \tt
+}
+\def\endcode{
+ \rm
+ \par
+ \bigskip
+ \leftskip0pt
+}
+
+
+%% end
+\endinput
+
diff --git a/doc/libs/dlmf.sty b/doc/libs/dlmf.sty
new file mode 100644
index 0000000..f435e96
--- /dev/null
+++ b/doc/libs/dlmf.sty
@@ -0,0 +1,55 @@
+%% Copyright 2021 Ian Jauslin
+%%
+%% 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.
+
+%%
+%% DLMF package:
+%% cite equations from DLMF
+%%
+
+%% TeX format
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+
+%% package name
+\ProvidesPackage{dlmf}[2020/05/01]
+
+%% dependencies
+\RequirePackage{color}
+\RequirePackage{hyperref}
+
+% get the first two numbers in (a.b.c);
+\def\@sectionnr(#1.#2.#3){#1.#2}
+
+% get the last number in (a.b.c);
+\def\@eqnr(#1.#2.#3){#3}
+
+% remove parentheses around argument
+\def\@cleanparentheses(#1){#1}
+
+%% cite DLMF equation
+\def\dlmfcite#1#2{\leavevmode%
+ \let\@dlmfcite@separator\@empty%
+ \cite[%
+ % loop over ',' separated list
+ \@for\@dlmfcite:=#1\do{%
+ % put commas between entries
+ \@dlmfcite@separator\def\@dlmfcite@separator{,\ }%
+ ({\color{blue}\href{https://dlmf.nist.gov/\expandafter\@sectionnr\@dlmfcite\#E\expandafter\@eqnr\@dlmfcite}{\expandafter\@cleanparentheses\@dlmfcite}})%
+ }%
+ ]{DLMF#2}%
+}
+
+%% end
+\endinput
+
+
diff --git a/doc/libs/ian.cls b/doc/libs/ian.cls
new file mode 100644
index 0000000..f29e6bd
--- /dev/null
+++ b/doc/libs/ian.cls
@@ -0,0 +1,682 @@
+%%
+%% Ian's class file
+%%
+
+%% TeX format
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+
+%% class name
+\ProvidesClass{ian}[2017/09/29]
+
+%% boolean to signal that this class is being used
+\newif\ifianclass
+
+%% options
+% no section numbering in equations
+\DeclareOption{section_in_eq}{\sectionsineqtrue}
+\DeclareOption{section_in_fig}{\sectionsinfigtrue}
+\DeclareOption{section_in_theo}{\PassOptionsToPackage{\CurrentOption}{iantheo}}
+\DeclareOption{section_in_all}{\sectionsineqtrue\sectionsinfigtrue\PassOptionsToPackage{section_in_theo}{iantheo}}
+\DeclareOption{subsection_in_eq}{\subsectionsineqtrue}
+\DeclareOption{subsection_in_fig}{\subsectionsinfigtrue}
+\DeclareOption{subsection_in_theo}{\PassOptionsToPackage{\CurrentOption}{iantheo}}
+\DeclareOption{subsection_in_all}{\subsectionsineqtrue\subsectionsinfigtrue\PassOptionsToPackage{subsection_in_theo}{iantheo}}
+\DeclareOption{no_section_in_eq}{\sectionsineqfalse}
+\DeclareOption{no_section_in_fig}{\sectionsinfigfalse}
+\DeclareOption{no_section_in_theo}{\PassOptionsToPackage{\CurrentOption}{iantheo}}
+\DeclareOption{no_section_in_all}{\sectionsineqfalse\sectionsinfigfalse\PassOptionsToPackage{no_section_in_theo}{iantheo}}
+\DeclareOption{no_subsection_in_eq}{\subsectionsineqfalse}
+\DeclareOption{no_subsection_in_fig}{\subsectionsinfigfalse}
+\DeclareOption{no_subsection_in_theo}{\PassOptionsToPackage{\CurrentOption}{iantheo}}
+\DeclareOption{no_subsection_in_all}{\subsectionsineqfalse\subsectionsinfigfalse\PassOptionsToPackage{no_subsection_in_theo}{iantheo}}
+% reset point
+\DeclareOption{point_reset_at_section}{\PassOptionsToPackage{reset_at_section}{point}}
+\DeclareOption{point_no_reset_at_section}{\PassOptionsToPackage{no_reset_at_section}{point}}
+\DeclareOption{point_reset_at_theo}{\PassOptionsToPackage{reset_at_theo}{point}}
+\DeclareOption{point_no_reset_at_theo}{\PassOptionsToPackage{no_reset_at_theo}{point}}
+
+\def\ian@defaultoptions{
+ \ExecuteOptions{section_in_all, no_subsection_in_all}
+ \ProcessOptions
+
+ %% required packages
+ \RequirePackage{iantheo}
+ \RequirePackage{point}
+ \RequirePackage{color}
+ \RequirePackage{marginnote}
+ \RequirePackage{amssymb}
+ \PassOptionsToPackage{hidelinks}{hyperref}
+ \RequirePackage{hyperref}
+}
+
+%% paper dimensions
+\setlength\paperheight{297mm}
+\setlength\paperwidth{210mm}
+
+%% fonts
+\input{size11.clo}
+\DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm}
+\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf}
+\DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt}
+\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf}
+\DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit}
+
+%% text dimensions
+\hoffset=-50pt
+\voffset=-72pt
+\textwidth=460pt
+\textheight=704pt
+
+
+%% remove default indentation
+\parindent=0pt
+%% indent command
+\def\indent{\hskip20pt}
+
+%% something is wrong with \thepage, redefine it
+\gdef\thepage{\the\c@page}
+
+%% array lines (to use the array environment)
+\setlength\arraycolsep{5\p@}
+\setlength\arrayrulewidth{.4\p@}
+
+
+%% correct vertical alignment at the end of a document
+\AtEndDocument{
+ \vfill
+ \eject
+}
+
+
+%% hyperlinks
+% hyperlinkcounter
+\newcounter{lncount}
+% hyperref anchor
+\def\hrefanchor{%
+\stepcounter{lncount}%
+\hypertarget{ln.\thelncount}{}%
+}
+
+%% define a command and write it to aux file
+\def\outdef#1#2{%
+ % define command%
+ \expandafter\xdef\csname #1\endcsname{#2}%
+ % hyperlink number%
+ \expandafter\xdef\csname #1@hl\endcsname{\thelncount}%
+ % write command to aux%
+ \immediate\write\@auxout{\noexpand\expandafter\noexpand\gdef\noexpand\csname #1\endcsname{\csname #1\endcsname}}%
+ \immediate\write\@auxout{\noexpand\expandafter\noexpand\gdef\noexpand\csname #1@hl\endcsname{\thelncount}}%
+}
+
+%% can call commands even when they are not defined
+\def\safe#1{%
+ \ifdefined#1%
+ #1%
+ \else%
+ {\color{red}\bf?}%
+ \fi%
+}
+
+%% define a label for the latest tag
+%% label defines a command containing the string stored in \tag
+\def\deflabel{
+ \def\label##1{\expandafter\outdef{label@##1}{\safe\tag}}
+
+ \def\ref##1{%
+ % check whether the label is defined (hyperlink runs into errors if this check is omitted)
+ \ifcsname label@##1@hl\endcsname%
+ \hyperlink{ln.\csname label@##1@hl\endcsname}{{\color{blue}\safe\csname label@##1\endcsname}}%
+ \else%
+ \ifcsname label@##1\endcsname%
+ {\color{blue}\csname ##1\endcsname}%
+ \else%
+ {\bf ??}%
+ \fi%
+ \fi%
+ }
+ % manually specify label for ref
+ \def\refname##1##2{%
+ % check whether the label is defined (hyperlink runs into errors if this check is omitted)
+ \ifcsname label@##1@hl\endcsname%
+ \hyperlink{ln.\csname label@##1@hl\endcsname}{{\color{blue}##2}}%
+ \else%
+ ??##2%
+ \fi%
+ }
+}
+
+
+%% make a custom link at any given location in the document
+\def\makelink#1#2{%
+ \hrefanchor%
+ \outdef{label@#1}{#2}%
+}
+
+
+%% section command
+% counter
+\newcounter{sectioncount}
+% space before section
+\newlength\secskip
+\setlength\secskip{40pt}
+% a prefix to put before the section number, e.g. A for appendices
+\def\sectionprefix{}
+% define some lengths
+\newlength\secnumwidth
+\newlength\sectitlewidth
+\def\section#1{
+ % reset counters
+ \stepcounter{sectioncount}
+ \setcounter{subsectioncount}{0}
+ \ifsectionsineq
+ \setcounter{seqcount}0
+ \fi
+ \ifsectionsinfig
+ \setcounter{figcount}0
+ \fi
+
+ % space before section (if not first)
+ \ifnum\thesectioncount>1
+ \vskip\secskip
+ \penalty-1000
+ \fi
+
+ % hyperref anchor
+ \hrefanchor
+ % define tag (for \label)
+ \xdef\tag{\sectionprefix\thesectioncount}
+
+ % get widths
+ \def\@secnum{{\bf\Large\sectionprefix\thesectioncount.\hskip10pt}}
+ \settowidth\secnumwidth{\@secnum}
+ \setlength\sectitlewidth\textwidth
+ \addtolength\sectitlewidth{-\secnumwidth}
+
+ % print name
+ \parbox{\textwidth}{
+ \@secnum
+ \parbox[t]{\sectitlewidth}{\Large\bf #1}}
+
+ % write to table of contents
+ \iftoc
+ % save lncount in aux variable which is written to toc
+ \immediate\write\tocoutput{\noexpand\expandafter\noexpand\edef\noexpand\csname toc@sec.\thesectioncount\endcsname{\thelncount}}
+ \write\tocoutput{\noexpand\tocsection{#1}{\thepage}}
+ \fi
+
+ %space
+ \par\penalty10000
+ \bigskip\penalty10000
+}
+
+%% subsection
+% counter
+\newcounter{subsectioncount}
+% space before subsection
+\newlength\subsecskip
+\setlength\subsecskip{30pt}
+\def\subsection#1{
+ % counters
+ \stepcounter{subsectioncount}
+ \setcounter{subsubsectioncount}{0}
+ \ifsubsectionsineq
+ \setcounter{seqcount}0
+ \fi
+ \ifsubsectionsinfig
+ \setcounter{figcount}0
+ \fi
+
+ % space before subsection (if not first)
+ \ifnum\thesubsectioncount>1
+ \vskip\subsecskip
+ \penalty-500
+ \fi
+
+ % hyperref anchor
+ \hrefanchor
+ % define tag (for \label)
+ \xdef\tag{\sectionprefix\thesectioncount.\thesubsectioncount}
+
+ % get widths
+ \def\@secnum{{\bf\large\hskip.5cm\sectionprefix\thesectioncount.\thesubsectioncount.\hskip5pt}}
+ \settowidth\secnumwidth{\@secnum}
+ \setlength\sectitlewidth\textwidth
+ \addtolength\sectitlewidth{-\secnumwidth}
+ % print name
+ \parbox{\textwidth}{
+ \@secnum
+ \parbox[t]{\sectitlewidth}{\large\bf #1}}
+
+ % write to table of contents
+ \iftoc
+ % save lncount in aux variable which is written to toc
+ \immediate\write\tocoutput{\noexpand\expandafter\noexpand\edef\noexpand\csname toc@subsec.\thesectioncount.\thesubsectioncount\endcsname{\thelncount}}
+ \write\tocoutput{\noexpand\tocsubsection{#1}{\thepage}}
+ \fi
+
+ % space
+ \par\penalty10000
+ \medskip\penalty10000
+}
+
+%% subsubsection
+% counter
+\newcounter{subsubsectioncount}
+% space before subsubsection
+\newlength\subsubsecskip
+\setlength\subsubsecskip{20pt}
+\def\subsubsection#1{
+ % counters
+ \stepcounter{subsubsectioncount}
+
+ % space before subsubsection (if not first)
+ \ifnum\thesubsubsectioncount>1
+ \vskip\subsubsecskip
+ \penalty-500
+ \fi
+
+ % hyperref anchor
+ \hrefanchor
+ % define tag (for \label)
+ \xdef\tag{\sectionprefix\thesectioncount.\thesubsectioncount.\thesubsubsectioncount}
+
+ % get widths
+ \def\@secnum{{\bf\hskip1.cm\sectionprefix\thesectioncount.\thesubsectioncount.\thesubsubsectioncount.\hskip5pt}}
+ \settowidth\secnumwidth{\@secnum}
+ \setlength\sectitlewidth\textwidth
+ \addtolength\sectitlewidth{-\secnumwidth}
+ % print name
+ \parbox{\textwidth}{
+ \@secnum
+ \parbox[t]{\sectitlewidth}{\large\bf #1}}
+
+ % write to table of contents
+ \iftoc
+ % save lncount in aux variable which is written to toc
+ \immediate\write\tocoutput{\noexpand\expandafter\noexpand\edef\noexpand\csname toc@subsubsec.\thesectioncount.\thesubsectioncount.\thesubsubsectioncount\endcsname{\thelncount}}
+ \write\tocoutput{\noexpand\tocsubsubsection{#1}{\thepage}}
+ \fi
+
+ % space
+ \par\penalty10000
+ \medskip\penalty10000
+}
+
+%% itemize
+\newlength\itemizeskip
+% left margin for items
+\setlength\itemizeskip{20pt}
+\newlength\itemizeseparator
+% space between the item symbol and the text
+\setlength\itemizeseparator{5pt}
+% penalty preceding an itemize
+\newcount\itemizepenalty
+\itemizepenalty=0
+% counter counting the itemize level
+\newcounter{itemizecount}
+
+% item symbol
+\def\itemizept#1{
+ \ifnum#1=1
+ \textbullet
+ \else
+ $\scriptstyle\blacktriangleright$
+ \fi
+}
+
+
+\newlength\current@itemizeskip
+\setlength\current@itemizeskip{0pt}
+\def\itemize{%
+ \par\expandafter\penalty\the\itemizepenalty\medskip\expandafter\penalty\the\itemizepenalty%
+ \addtocounter{itemizecount}{1}%
+ \addtolength\current@itemizeskip{\itemizeskip}%
+ \leftskip\current@itemizeskip%
+}
+\def\enditemize{%
+ \addtocounter{itemizecount}{-1}%
+ \addtolength\current@itemizeskip{-\itemizeskip}%
+ \par\expandafter\penalty\the\itemizepenalty\leftskip\current@itemizeskip%
+ \medskip\expandafter\penalty\the\itemizepenalty%
+}
+
+% item, with optional argument to specify the item point
+% @itemarg is set to true when there is an optional argument
+\newif\if@itemarg
+\def\item{%
+ % check whether there is an optional argument (if there is none, add on empty '[]')
+ \@ifnextchar [{\@itemargtrue\@itemx}{\@itemargfalse\@itemx[]}%
+}
+\newlength\itempt@total
+\def\@itemx[#1]{
+ \if@itemarg
+ \settowidth\itempt@total{#1}
+ \else
+ \settowidth\itempt@total{\itemizept\theitemizecount}
+ \fi
+ \addtolength\itempt@total{\itemizeseparator}
+ \par
+ \medskip
+ \if@itemarg
+ \hskip-\itempt@total#1\hskip\itemizeseparator
+ \else
+ \hskip-\itempt@total\itemizept\theitemizecount\hskip\itemizeseparator
+ \fi
+}
+
+%% prevent page breaks after itemize
+\newcount\previtemizepenalty
+\def\nopagebreakafteritemize{
+ \previtemizepenalty=\itemizepenalty
+ \itemizepenalty=10000
+}
+%% back to previous value
+\def\restorepagebreakafteritemize{
+ \itemizepenalty=\previtemizepenalty
+}
+
+%% enumerate
+\newcounter{enumerate@count}
+\def\enumerate{
+ \setcounter{enumerate@count}0
+ \let\olditem\item
+ \let\olditemizept\itemizept
+ \def\item{
+ % counter
+ \stepcounter{enumerate@count}
+ % set header
+ \def\itemizept{\theenumerate@count.}
+ % hyperref anchor
+ \hrefanchor
+ % define tag (for \label)
+ \xdef\tag{\theenumerate@count}
+ \olditem
+ }
+ \itemize
+}
+\def\endenumerate{
+ \enditemize
+ \let\item\olditem
+ \let\itemizept\olditemizept
+}
+
+
+%% equation numbering
+% counter
+\newcounter{seqcount}
+% booleans (write section or subsection in equation number)
+\newif\ifsectionsineq
+\newif\ifsubsectionsineq
+\def\seqcount{
+ \stepcounter{seqcount}
+ % the output
+ \edef\seqformat{\theseqcount}
+ % add subsection number
+ \ifsubsectionsineq
+ \let\tmp\seqformat
+ \edef\seqformat{\thesubsectioncount.\tmp}
+ \fi
+ % add section number
+ \ifsectionsineq
+ \let\tmp\seqformat
+ \edef\seqformat{\sectionprefix\thesectioncount.\tmp}
+ \fi
+ % define tag (for \label)
+ \xdef\tag{\seqformat}
+ % write number
+ \marginnote{\hfill(\seqformat)}
+}
+%% equation environment compatibility
+\def\equation{\hrefanchor$$\seqcount}
+\def\endequation{$$\@ignoretrue}
+
+
+%% figures
+% counter
+\newcounter{figcount}
+% booleans (write section or subsection in equation number)
+\newif\ifsectionsinfig
+\newif\ifsubsectionsinfig
+% width of figures
+\newlength\figwidth
+\setlength\figwidth\textwidth
+\addtolength\figwidth{-2.5cm}
+% caption
+\def\defcaption{
+ \long\def\caption##1{
+ \stepcounter{figcount}
+
+ % hyperref anchor
+ \hrefanchor
+
+ % the number of the figure
+ \edef\figformat{\thefigcount}
+ % add subsection number
+ \ifsubsectionsinfig
+ \let\tmp\figformat
+ \edef\figformat{\thesubsectioncount.\tmp}
+ \fi
+ % add section number
+ \ifsectionsinfig
+ \let\tmp\figformat
+ \edef\figformat{\sectionprefix\thesectioncount.\tmp}
+ \fi
+
+ % define tag (for \label)
+ \xdef\tag{\figformat}
+
+ % write
+ \hfil fig \figformat: \parbox[t]{\figwidth}{\leavevmode\small##1}
+
+ % space
+ \par\bigskip
+ }
+}
+%% short caption: centered
+\def\captionshort#1{
+ \stepcounter{figcount}
+
+ % hyperref anchor
+ \hrefanchor
+
+ % the number of the figure
+ \edef\figformat{\thefigcount}
+ % add section number
+ \ifsectionsinfig
+ \let\tmp\figformat
+ \edef\figformat{\sectionprefix\thesectioncount.\tmp}
+ \fi
+
+ % define tag (for \label)
+ \xdef\tag{\figformat}
+
+ % write
+ \hfil fig \figformat: {\small#1}
+
+ %space
+ \par\bigskip
+}
+
+%% environment
+\def\figure{
+ \par
+ \vfil\penalty100\vfilneg
+ \bigskip
+}
+\def\endfigure{
+ \par
+ \bigskip
+}
+
+
+%% start appendices
+\def\appendix{
+ \vfill
+ \pagebreak
+
+ % counter
+ \setcounter{sectioncount}0
+
+ % prefix
+ \def\sectionprefix{A}
+
+ % write
+ {\bf \LARGE Appendices}\par\penalty10000\bigskip\penalty10000
+
+ % add a mention in the table of contents
+ \iftoc
+ \immediate\write\tocoutput{\noexpand\tocappendices}\penalty10000
+ \fi
+
+ %% uncomment for new page for each appendix
+ %\def\seqskip{\vfill\pagebreak}
+}
+
+
+%% bibliography
+% size of header
+\newlength\bibheader
+\def\thebibliography#1{
+ \hrefanchor
+
+ % add a mention in the table of contents
+ \iftoc
+ % save lncount in aux variable which is written to toc
+ \immediate\write\tocoutput{\noexpand\expandafter\noexpand\edef\noexpand\csname toc@references\endcsname{\thelncount}}
+ \write\tocoutput{\noexpand\tocreferences{\thepage}}\penalty10000
+ \fi
+
+ % write
+ {\bf \LARGE References}\par\penalty10000\bigskip\penalty10000
+ % width of header
+ \settowidth\bibheader{[#1]}
+ \leftskip\bibheader
+}
+% end environment
+\def\endthebibliography{
+ \par\leftskip0pt
+}
+
+%% bibitem command
+\def\bibitem[#1]#2{%
+ \hrefanchor%
+ \outdef{label@cite#2}{#1}%
+ \hskip-\bibheader%
+ \makebox[\bibheader]{\cite{#2}\hfill}%
+}
+
+%% cite command
+% @tempswa is set to true when there is an optional argument
+\newif\@tempswa
+\def\cite{%
+ % check whether there is an optional argument (if there is none, add on empty '[]')
+ \@ifnextchar [{\@tempswatrue\@citex}{\@tempswafalse\@citex[]}%
+}
+% command with optional argument
+\def\@citex[#1]#2{\leavevmode%
+ % initialize loop
+ \let\@cite@separator\@empty%
+ % format
+ \@cite{%
+ % loop over ',' separated list
+ \@for\@cite@:=#2\do{%
+ % text to add at each iteration of the loop (separator between citations)
+ \@cite@separator\def\@cite@separator{,\ }%
+ % add entry to citelist
+ \@writecitation{\@cite@}%
+ \ref{cite\@cite@}%
+ }%
+ }%
+ % add optional argument text (as an argument to '\@cite')
+ {#1}%
+}
+\def\@cite#1#2{%
+ [#1\if@tempswa , #2\fi]%
+}
+%% add entry to citelist after checking it has not already been added
+\def\@writecitation#1{%
+ \ifcsname if#1cited\endcsname%
+ \else%
+ \expandafter\newif\csname if#1cited\endcsname%
+ \immediate\write\@auxout{\string\citation{#1}}%
+ \fi%
+}
+
+%% table of contents
+% boolean
+\newif\iftoc
+\def\tableofcontents{
+ {\bf \large Table of contents:}\par\penalty10000\bigskip\penalty10000
+
+ % copy content from file
+ \IfFileExists{\jobname.toc}{\input{\jobname.toc}}{{\tt error: table of contents missing}}
+
+ % open new toc
+ \newwrite\tocoutput
+ \immediate\openout\tocoutput=\jobname.toc
+
+ \toctrue
+}
+%% close file
+\AtEndDocument{
+ % close toc
+ \iftoc
+ \immediate\closeout\tocoutput
+ \fi
+}
+
+
+%% fill line with dots
+\def\leaderfill{\leaders\hbox to 1em {\hss. \hss}\hfill}
+
+%% same as sectionprefix
+\def\tocsectionprefix{}
+
+%% toc formats
+\newcounter{tocsectioncount}
+\def\tocsection #1#2{
+ \stepcounter{tocsectioncount}
+ \setcounter{tocsubsectioncount}{0}
+ \setcounter{tocsubsubsectioncount}{0}
+ % write
+ \smallskip\hyperlink{ln.\csname toc@sec.\thetocsectioncount\endcsname}{{\bf \tocsectionprefix\thetocsectioncount}.\hskip5pt {\color{blue}#1}\leaderfill#2}\par
+}
+\newcounter{tocsubsectioncount}
+\def\tocsubsection #1#2{
+ \stepcounter{tocsubsectioncount}
+ \setcounter{tocsubsubsectioncount}{0}
+ % write
+ {\hskip10pt\hyperlink{ln.\csname toc@subsec.\thetocsectioncount.\thetocsubsectioncount\endcsname}{{\bf \thetocsectioncount.\thetocsubsectioncount}.\hskip5pt {\color{blue}\small #1}\leaderfill#2}}\par
+}
+\newcounter{tocsubsubsectioncount}
+\def\tocsubsubsection #1#2{
+ \stepcounter{tocsubsubsectioncount}
+ % write
+ {\hskip20pt\hyperlink{ln.\csname toc@subsubsec.\thetocsectioncount.\thetocsubsectioncount.\thetocsubsubsectioncount\endcsname}{{\bf \thetocsectioncount.\thetocsubsectioncount.\thetocsubsubsectioncount}.\hskip5pt {\color{blue}\small #1}\leaderfill#2}}\par
+}
+\def\tocappendices{
+ \medskip
+ \setcounter{tocsectioncount}0
+ {\bf Appendices}\par
+ \smallskip
+ \def\tocsectionprefix{A}
+}
+\def\tocreferences#1{
+ \medskip
+ {\hyperlink{ln.\csname toc@references\endcsname}{{\color{blue}\bf References}\leaderfill#1}}\par
+ \smallskip
+}
+
+
+%% definitions that must be loaded at begin document
+\let\ian@olddocument\document
+\def\document{
+ \ian@olddocument
+
+ \deflabel
+ \defcaption
+}
+
+%% end
+\ian@defaultoptions
+\endinput
diff --git a/doc/libs/iantheo.sty b/doc/libs/iantheo.sty
new file mode 100644
index 0000000..1945a5f
--- /dev/null
+++ b/doc/libs/iantheo.sty
@@ -0,0 +1,176 @@
+%% Copyright 2021 Ian Jauslin
+%%
+%% 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.
+
+%%
+%% iantheorem package:
+%% Ian's customized theorem command
+%%
+
+%% boolean to signal that this package was loaded
+\newif\ifiantheo
+
+%% TeX format
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+
+%% package name
+\ProvidesPackage{iantheo}[2016/11/10]
+
+%% options
+\newif\ifsectionintheo
+\DeclareOption{section_in_theo}{\sectionintheotrue}
+\DeclareOption{no_section_in_theo}{\sectionintheofalse}
+\newif\ifsubsectionintheo
+\DeclareOption{subsection_in_theo}{\subsectionintheotrue}
+\DeclareOption{no_subsection_in_theo}{\subsectionintheofalse}
+
+\def\iantheo@defaultoptions{
+ \ExecuteOptions{section_in_theo, no_subsection_in_theo}
+ \ProcessOptions
+
+ %%% reset at every new section
+ \ifsectionintheo
+ \let\iantheo@oldsection\section
+ \gdef\section{\setcounter{theocount}{0}\iantheo@oldsection}
+ \fi
+
+ %% reset at every new subsection
+ \ifsubsectionintheo
+ \let\iantheo@oldsubsection\subsection
+ \gdef\subsection{\setcounter{theocount}{0}\iantheo@oldsubsection}
+ \fi
+}
+
+
+%% delimiters
+\def\delimtitle#1{
+ \par%
+ \leavevmode%
+ \raise.3em\hbox to\hsize{%
+ \lower0.3em\hbox{\vrule height0.3em}%
+ \hrulefill%
+ \ \lower.3em\hbox{#1}\ %
+ \hrulefill%
+ \lower0.3em\hbox{\vrule height0.3em}%
+ }%
+ \par\penalty10000%
+}
+
+%% callable by ref
+\def\delimtitleref#1{
+ \par%
+%
+ \ifdefined\ianclass%
+ % hyperref anchor%
+ \hrefanchor%
+ % define tag (for \label)%
+ \xdef\tag{#1}%
+ \fi%
+%
+ \leavevmode%
+ \raise.3em\hbox to\hsize{%
+ \lower0.3em\hbox{\vrule height0.3em}%
+ \hrulefill%
+ \ \lower.3em\hbox{\bf #1}\ %
+ \hrulefill%
+ \lower0.3em\hbox{\vrule height0.3em}%
+ }%
+ \par\penalty10000%
+}
+
+%% no title
+\def\delim{
+ \par%
+ \leavevmode\raise.3em\hbox to\hsize{%
+ \lower0.3em\hbox{\vrule height0.3em}%
+ \hrulefill%
+ \lower0.3em\hbox{\vrule height0.3em}%
+ }%
+ \par\penalty10000%
+}
+
+%% end delim
+\def\enddelim{
+ \par\penalty10000%
+ \leavevmode%
+ \raise.3em\hbox to\hsize{%
+ \vrule height0.3em\hrulefill\vrule height0.3em%
+ }%
+ \par%
+}
+
+
+%% theorem
+% counter
+\newcounter{theocount}
+% booleans (write section or subsection in equation number)
+\def\theo#1{
+ \stepcounter{theocount}
+ \ifdefined\ianclass
+ % hyperref anchor
+ \hrefanchor
+ \fi
+ % the number
+ \def\formattheo{\thetheocount}
+ % add subsection number
+ \ifsubsectionintheo
+ \let\tmp\formattheo
+ \edef\formattheo{\thesubsectioncount.\tmp}
+ \fi
+ % add section number
+ \ifsectionintheo
+ \let\tmp\formattheo
+ \edef\formattheo{\sectionprefix\thesectioncount.\tmp}
+ \fi
+ % define tag (for \label)
+ \xdef\tag{\formattheo}
+ % write
+ \delimtitle{\bf #1 \formattheo}
+}
+\let\endtheo\enddelim
+%% theorem headers with name
+\def\theoname#1#2{
+ \theo{#1}\hfil({\it #2})\par\penalty10000\medskip%
+}
+
+
+%% qed symbol
+\def\qedsymbol{$\square$}
+\def\qed{\penalty10000\hfill\penalty10000\qedsymbol}
+
+
+%% compatibility with article class
+\ifdefined\ianclasstrue
+ \relax
+\else
+ \def\thesectioncount{\thesection}
+ \def\thesubsectioncount{\thesubsection}
+ \def\sectionprefix{}
+\fi
+
+
+%% prevent page breaks after displayed equations
+\newcount\prevpostdisplaypenalty
+\def\nopagebreakaftereq{
+ \prevpostdisplaypenalty=\postdisplaypenalty
+ \postdisplaypenalty=10000
+}
+%% back to previous value
+\def\restorepagebreakaftereq{
+ \postdisplaypenalty=\prevpostdisplaypenalty
+}
+
+
+%% end
+\iantheo@defaultoptions
+\endinput
diff --git a/doc/libs/largearray.sty b/doc/libs/largearray.sty
new file mode 100644
index 0000000..cf9075f
--- /dev/null
+++ b/doc/libs/largearray.sty
@@ -0,0 +1,33 @@
+%% Copyright 2021 Ian Jauslin
+%%
+%% 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.
+
+%%
+%% largearray package:
+%% Array spanning the entire line
+%%
+
+%% TeX format
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+
+%% package name
+\ProvidesPackage{largearray}[2016/11/10]
+
+\RequirePackage{array}
+
+%% array spanning the entire line
+\newlength\largearray@width
+\setlength\largearray@width\textwidth
+\addtolength\largearray@width{-10pt}
+\def\largearray{\begin{array}{@{}>{\displaystyle}l@{}}\hphantom{\hspace{\largearray@width}}\\[-.5cm]}
+\def\endlargearray{\end{array}}
diff --git a/doc/libs/point.sty b/doc/libs/point.sty
new file mode 100644
index 0000000..a396d1c
--- /dev/null
+++ b/doc/libs/point.sty
@@ -0,0 +1,128 @@
+%% Copyright 2021 Ian Jauslin
+%%
+%% 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.
+
+%%
+%% Points package:
+%% \point commands
+%%
+
+%% TeX format
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+
+%% package name
+\ProvidesPackage{point}[2017/06/13]
+
+%% options
+\newif\ifresetatsection
+\DeclareOption{reset_at_section}{\resetatsectiontrue}
+\DeclareOption{no_reset_at_section}{\resetatsectionfalse}
+\newif\ifresetatsubsection
+\DeclareOption{reset_at_subsection}{\resetatsubsectiontrue}
+\DeclareOption{no_reset_at_subsection}{\resetatsubsectionfalse}
+\newif\ifresetatsubsubsection
+\DeclareOption{reset_at_subsubsection}{\resetatsubsubsectiontrue}
+\DeclareOption{no_reset_at_subsubsection}{\resetatsubsubsectionfalse}
+\newif\ifresetattheo
+\DeclareOption{reset_at_theo}{\resetattheotrue}
+\DeclareOption{no_reset_at_theo}{\resetattheofalse}
+
+\def\point@defaultoptions{
+ \ExecuteOptions{reset_at_section, reset_at_subsection, reset_at_subsubsection, no_reset_at_theo}
+ \ProcessOptions
+
+ %% reset at every new section
+ \ifresetatsection
+ \let\point@oldsection\section
+ \gdef\section{\resetpointcounter\point@oldsection}
+ \fi
+ %% reset at every new subsection
+ \ifresetatsubsection
+ \let\point@oldsubsection\subsection
+ \gdef\subsection{\resetpointcounter\point@oldsubsection}
+ \fi
+ %% reset at every new subsubsection
+ \ifresetatsubsubsection
+ \let\point@oldsubsubsection\subsubsection
+ \gdef\subsubsection{\resetpointcounter\point@oldsubsubsection}
+ \fi
+
+ %% reset at every new theorem
+ \ifresetattheo
+ \ifdefined\iantheotrue
+ \let\point@oldtheo\theo
+ \gdef\theo{\resetpointcounter\point@oldtheo}
+ \fi
+ \fi
+}
+
+
+%% point
+% counter
+\newcounter{pointcount}
+\def\point{
+ \stepcounter{pointcount}
+ \setcounter{subpointcount}{0}
+ % hyperref anchor (only if the class is 'ian')
+ \ifdefined\ifianclass
+ \hrefanchor
+ % define tag (for \label)
+ \xdef\tag{\thepointcount}
+ \fi
+ % header
+ \indent{\bf \thepointcount\ - }
+}
+
+%% subpoint
+% counter
+\newcounter{subpointcount}
+\def\subpoint{
+ \stepcounter{subpointcount}
+ \setcounter{subsubpointcount}0
+ % hyperref anchor (only if the class is 'ian')
+ \ifdefined\ifianclass
+ \hrefanchor
+ % define tag (for \label)
+ \xdef\tag{\thepointcount-\thesubpointcount}
+ \fi
+ % header
+ \indent\hskip.5cm{\bf \thepointcount-\thesubpointcount\ - }
+}
+
+%% subsubpoint
+% counter
+\newcounter{subsubpointcount}
+\def\subsubpoint{
+ \stepcounter{subsubpointcount}
+ % hyperref anchor (only if the class is 'ian')
+ \ifdefined\ifianclass
+ \hrefanchor
+ % define tag (for \label)
+ \xdef\tag{\thepointcount-\thesubpointcount-\thesubsubpointcount}
+ \fi
+ \indent\hskip1cm{\bf \thepointcount-\thesubpointcount-\thesubsubpointcount\ - }
+}
+
+
+%% reset point counters
+\def\resetpointcounter{
+ \setcounter{pointcount}{0}
+ \setcounter{subpointcount}{0}
+ \setcounter{subsubpointcount}{0}
+}
+
+
+
+%% end
+\point@defaultoptions
+\endinput
diff --git a/doc/simplesolv-doc.tex b/doc/simplesolv-doc.tex
new file mode 100644
index 0000000..722282a
--- /dev/null
+++ b/doc/simplesolv-doc.tex
@@ -0,0 +1,3679 @@
+%% Copyright 2021 Ian Jauslin
+%%
+%% 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.
+
+\documentclass[subsection_in_all]{ian}
+
+\usepackage{code}
+\usepackage{dsfont}
+\usepackage{largearray}
+\usepackage{dlmf}
+
+\def\Eta{H}
+
+\begin{document}
+
+\hbox{}
+\hfil{\bf\Large
+{\tt simplesolv}\par
+\medskip
+\hfil \large v0.3
+}
+
+\vfill
+
+\tableofcontents
+
+\vfill
+\eject
+
+\setcounter{page}1
+\pagestyle{plain}
+
+\indent
+{\tt simplesolv} is a tool to compute the solution of the equations of the ``Simplified approach'' to the repulsive Bose gas introduced in\-~\cite{CJL20,CJL20b,CHe21}.
+This approach provides an approximation to various observables of the ground state of the Hamiltonian
+\begin{equation}
+ H_N=-\frac12\sum_{i=1}^N\Delta_i+\sum_{1\leqslant i\leqslant j\leqslant N}v(|x_i-x_j|)
+\end{equation}
+in three dimensions, with periodic boundary conditions, in the thermodynamic limit $N\to\infty$ at fixed density $\rho$.
+\bigskip
+
+\indent
+{\tt simplesolv} is written in {\tt julia}.
+The source code is located in the {\tt src} directory of this bundle.
+Throughout the documentation, we will refer to the directory containing the {\tt src} directory as the ``installation directory'', and will denote it by the bash variable {\tt\$SIMPLESOLV} (so that the main julia file, for instance, is located at {\tt \$SIMPLESOLV/src/main.jl}).
+\vskip20pt
+
+\section{Basic usage}
+\indent
+Denoting the location of the installation directory by {\tt\$SIMPLESOLV}, {\tt simplesolv} is run by calling
+\begin{code}
+ julia \$SIMPLESOLV/src/main.jl [args] <command>
+\end{code}
+where the optional arguments {\tt [args]} take the form {\tt [-p params] [-U potential] [-M method] [-s savefile]}.
+\bigskip
+
+\indent
+A few commands support multithreaded execution.
+To enable {\tt julia} to run on several processors, it should be run with the {\tt -p} option.
+For example, to run on 8 CPUs, run
+\begin{code}
+ julia -p 8 \$SIMPLESOLV/src/main.jl [args] <command>
+\end{code}
+\bigskip
+
+\indent
+{\tt command} specifies which computation is to be carried out, such as {\tt energy} to compute the ground state energy, or {\tt condensate\_fraction} for the uncondensed fraction.
+The list of available commands depends on the \refname{sec:methods}{{\tt method}} argument, which specifies one of the available methods to solve the equation at hand.
+The available methods are (see section\-~\ref{sec:methods} for further details)
+\begin{itemize}
+ \item \refname{sec:easyeq}{{\tt easyeq}} ({\bf default}) for the Simple or Medium equation, or any interpolation between them, with a soft potential using the Newton algorithm,
+ \item \refname{sec:anyeq}{{\tt anyeq}} for any equation in the ``Simplified approach'' using the Newton algorithm.
+ \item \refname{sec:simpleq-Kv}{{\tt simpleq-Kv}} for the Simple equation using explicit expressions involving $\mathfrak Kv$ (see\-~(\ref{Kv})),
+ \item \refname{sec:simpleq-hardcore}{{\tt simpleq-hardcore}} for the Simple equation with a hard core potential using the Newton algorithm,
+ \item \refname{sec:simpleq-iteration}{{\tt simpleq-iteration}} for the Simple equation with a soft potential using the iteration defined in\-~\cite{CJL20}.
+\end{itemize}
+Each method is described in detail below, along with the list of commands ({\tt command}) and parameters ({\tt params}) compatible with them.
+\bigskip
+
+\indent
+{\tt params} should be a `{\tt;}' separated list of entries, each of which is of the form {\tt key=value}.
+For example {\tt -p "rho=1e-6;v\_a=2"}.
+(Note that you should not end the list of parameters by a `{\tt;}', otherwise {\tt simplesolv} will interpret that as there being an empty parameter entry, which it cannot split into a key and value, and will fail.)
+\bigskip
+
+\indent
+\refname{sec:potentials}{{\tt potential}} specifies which potential $v$ should be used, from the following list (see section\-~\ref{sec:potentials} for further details).
+\begin{itemize}
+ \item \refname{sec:exp}{{\tt exp}} ({\bf default}) for $v(|x|)=ae^{-|x|}$,
+ \item \refname{sec:tent}{{\tt tent}} for $v(|x|)=\mathds 1_{|x|<b}a\frac{2\pi}{3}(1-\frac{|x|}b)^2(\frac{|x|}b+2)$,
+ \item \refname{sec:expcry}{{\tt expcry}} for $v(|x|)=e^{-|x|}-ae^{-b|x|}$,
+ \item \refname{sec:npt}{{\tt npt}} for $v(|x|)=x^2e^{-|x|}$,
+ \item \refname{sec:alg}{{\tt alg}} for $v(|x|)=\frac1{1+\frac14|x|^4}$,
+ \item \refname{sec:algwell}{{\tt algwell}} for $v(|x|)=\frac{1+a|x|^4}{(1+|x|^2)^4}$.
+ \item \refname{sec:exact}{{\tt exact}} for $v(|x|)=\frac{12c( |x|^6b^6(2e-b^2) +b^4|x|^4(9e-7b^2) +4b^2|x|^2(3e-2b^2) +(5e+16b^2))}{(1+b^2|x|^2)^2(4+b^2|x|^2)^2((1+b^2|x|^2)^2-c)}$
+\end{itemize}
+The parameters in the potential can be set using the {\tt params} argument: to set $a$ set {\tt v\_a}, to set $b$ set {\tt v\_b}, to set $c$ set {\tt v\_c}, and to set $e$ set {\tt v\_e}.
+\bigskip
+
+\indent
+{\tt savefile} can be used to accelerate the computation of observables in the \refname{eq:anyeq_compleq}{{\tt compleq}} equation.
+Indeed, as is discussed in section\-~\ref{sec:anyeq}, the computation of \refname{eq:anyeq_compleq}{{\tt compleq}} is based on the computation of a large matrix, which can be pre-computed, saved in a file using the \refname{command:anyeq_save_Abar}{{\tt save\_Abar}} command, and reused by specifying that file in the {\tt savefile} argument.
+
+\section{Methods}\label{sec:methods}
+\indent
+In this section, we describe the different computation methods.
+\bigskip
+
+\subsection{\tt easyeq}\label{sec:easyeq}
+\indent
+This method is used to solve a family of equations, called {\tt easyeq}, that interpolate between the Simple equation and the Medium equation:
+\begin{equation}
+ -\Delta u
+ =
+ v(1-u)-2\rho K+\rho^2 L
+ \label{easyeq}
+\end{equation}
+with
+\begin{equation}
+ K:=\beta_K u\ast S+(1-\beta_K)\frac{2e}\rho u
+ ,\quad
+ L:=\beta_Lu\ast u\ast S+(1-\beta_L)\frac{2e}\rho u\ast u
+ \label{easyeq_KL}
+\end{equation}
+\begin{equation}
+ S:=(1-u)v
+ ,\quad
+ e:=\frac\rho2\int dx\ (1-u(|x|))v(|x|)
+ .
+ \label{easyeq_Se}
+\end{equation}
+for a soft potential $v$ at density $\rho>0$.
+\bigskip
+
+\indent
+\makelink{eq:easyeq_simpleq}{}
+\makelink{eq:easyeq_medeq}{}
+The special choice $\beta_K=\beta_L=0$ is called the Simple equation ({\tt simpleq}), and the choice $\beta_K=\beta_L=1$ is called the Medium equation ({\tt medeq})
+\bigskip
+
+\subsubsection{Usage}
+\indent
+Unless otherwise noted, this method takes the following parameters (specified via the {\tt [-p params]} flag, as a `{\tt;}' separated list of entries).
+\begin{itemize}
+ \item\makelink{param:easyeq_rho}{}
+ {\tt rho} ({\tt Float64}, default: $10^{-6}$): density $\rho$.
+
+ \item\makelink{param:easyeq_tolerance}{}
+ {\tt tolerance} ({\tt Float64}, default: $10^{-11}$): maximal size of final step in Newton iteration.
+
+ \item\makelink{param:easyeq_maxiter}{}
+ {\tt maxiter} ({\tt Int64}, default: 21): maximal number of iterations of the Newton algorithm before giving up.
+
+ \item\makelink{param:easyeq_order}{}
+ {\tt order} ({\tt Int64}, default: 100): order used for all Gauss quadratures (denoted by $N$ below).
+
+ \item\makelink{param:easyeq_minlrho_init}{}
+ {\tt minlrho\_init} ({\tt Float64}, default: {\tt rho}): to initialize the Newton algorithm, we first compute the solution for a smaller $\rho$, {\tt minlrho} is the minimal value for $\log_{10}\rho$ to start this initialization process.
+
+ \item\makelink{param:easyeq_nlrho_init}{}
+ {\tt nlrho\_init} ({\tt Int64}, default: 1): number of steps in the initialization process described above. Set to 1 to disable the incremental initialization process.
+
+ \item\makelink{param:easyeq_bK}{}
+ {\tt bK}, {\tt bL} ({\tt Float64}, default: 1, 1): the values of $\beta_K$ and $\beta_L$.
+
+ \item\makelink{param:easyeq_eq}{}
+ {\tt eq} ({\tt String}, default: ``{\tt simpleq}'', acceptable values: ``{\tt simpleq}'', ``{\tt medeq}''): A shortcut to select either the \refname{eq:easyeq_simpleq}{Simple equation} ($\beta_K=\beta_L=0$) or the \refname{eq:easyeq_medeq}{Medium equation} ($\beta_L=\beta_K=1$). When this option is set, neither {\tt bK} nor {\tt bL} should be set.
+\end{itemize}
+\bigskip
+
+The available {\tt commands} are the following.
+
+\begin{itemize}
+ \item {\tt energy}\makelink{command:easyeq_energy}{}:
+ compute the energy $e$ at a given $\rho$.\par
+ \underline{Output}: [$e$] [Newton error $\epsilon$].
+
+ \item {\tt energy\_rho}\makelink{command:easyeq_energy_rho}{}:
+ compute the energy $e$ as a function of $\rho$.
+ The Newton algorithm is initialized with the hardcore scattering solution (\ref{easyeq_init}) for the lowest $\rho$, and with the previously computed $\rho$ for the larger densities.\par
+ \underline{Disabled parameters}: \refname{param:easyeq_rho}{{\tt rho}}, \refname{param:easyeq_minlrho_init}{{\tt minlrho\_init}} and \refname{param:easyeq_nlrho_init}{{\tt nlrho\_init}}.\par
+ \underline{Extra parameters}:
+ \begin{itemize}
+ \item\makelink{param:easyeq_minlrho}{}
+ {\tt minlrho} ({\tt Float64}, default: $10^{-6}$): minimal value for $\log_{10}\rho$.
+
+ \item\makelink{param:easyeq_maxlrho}{}
+ {\tt maxlrho} ({\tt Float64}, default: $10^{2}$): maximal value for $\log_{10}\rho$.
+
+ \item\makelink{param:easyeq_nlrho}{}
+ {\tt nlrho} ({\tt Int64}, default: $100$): number of values for $\rho$ (spaced logarithmically).
+
+ \item\makelink{param:easyeq_rhos}{}
+ {\tt rhos} ({\tt Array\{Float64\}}, default: $(10^{{\tt minlrho}+\frac{{\tt maxlrho}-{\tt minlrho}}{{\tt nlrho}}n})_n$: list of values for $\rho$, specified as a `{\tt,}' separated list.
+ \end{itemize}
+ \underline{Output} (one line for each value of $\rho$): [$\rho$] [$e$] [Newton error $\epsilon$].
+
+ \item\makelink{command:easyeq_condensate_fraction}{}
+ {\tt condensate\_fraction}: compute the uncondensed fraction $\eta$ at a given $\rho$.\par
+ \underline{Output}: [$\eta$] [Newton error $\epsilon$].
+
+ \item\makelink{command:easyeq_condensate_fraction_rho}{}
+ {\tt condensate\_fraction\_rho}: compute the uncondensed fraction $\eta$ as a function of $\rho$.
+ The Newton algorithm is initialized with the hardcore scattering solution (\ref{easyeq_init}) for the lowest $\rho$, and with the previously computed $\rho$ for the larger densities.\par
+ \underline{Disabled parameters}: same as \refname{command:easyeq_energy_rho}{{\tt energy\_rho}}.\par
+ \underline{Extra parameters}: same as \refname{command:easyeq_energy_rho}{{\tt energy\_rho}}.\par
+ \underline{Output} (one line for each value of $\rho$): [$\rho$] [$\eta$] [Newton error $\epsilon$].
+
+ \item\makelink{command:easyeq_uk}{}
+ {\tt uk}: compute the Fourier transform $\hat u(|k|)$.
+ The values $|k|$ at which $\hat u$ is computed are those coming from the Gauss quadratures, and cannot be set.\par
+ \underline{Output} (one line for each value of $|k|$): [$|k|$] [$\hat u(|k|)$]
+
+ \item\makelink{command:easyeq_ux}{}
+ {\tt ux}: compute $u$ as a function of $|x|$.\par
+ \underline{Extra parameters}:
+ \begin{itemize}
+ \item\makelink{param:easyeq_xmin}{}
+ {\tt xmin} ({\tt Float64}, default: 0): minimum of the range of $|x|$ to be printed.
+
+ \item\makelink{param:easyeq_xmax}{}
+ {\tt xmax} ({\tt Float64}, default: 100): maximum of the range of $|x|$ to be printed.
+
+ \item\makelink{param:easyeq_nx}{}
+ {\tt nx} ({\tt Int64}, default: 100): number of points to print (linearly spaced).
+ \end{itemize}
+ \underline{Output} (one line for each value of $x$): [$|x|$] [$u(|x|)$]
+
+ \item\makelink{command:easyeq_uux}{}
+ {\tt uux}: compute $2u-\rho u\ast u$ as a function of $|x|$.\par
+ \underline{Extra parameters}: Same as \refname{command:easyeq_ux}{{\tt ux}}.\par
+ \underline{Output} (one line for each value of $x$): [$|x|$] [$2u(|x|)-\rho u\ast u(|x|)$]
+
+\end{itemize}
+
+\subsubsection{Description}
+\point{\bf Fourier space formulation.}
+The computation is carried out in Fourier space.
+We take the convention that the Fourier transform of a function $f(|x|)$ is
+\begin{equation}
+ \hat f(|k|)=\int_{\mathbb R^3} dx\ e^{ikx}f(|x|)
+ =\frac{4\pi}{|k|}\int_0^\infty dr\ \frac{\sin(|k|r)}rf(r)
+ .
+\end{equation}
+In Fourier space, (\ref{easyeq}) becomes
+\begin{equation}
+ k^2\hat u=\hat S-2\rho\hat A_K\hat u+\rho^2\hat A_L\hat u^2
+\end{equation}
+\begin{equation}
+ \hat A_K:=\beta_K\hat S+(1-\beta_K)\frac{2e}\rho
+ ,\quad
+ \hat A_L:=\beta_L\hat S+(1-\beta_L)\frac{2e}\rho
+\end{equation}
+with
+\begin{equation}
+ \hat S(|k|)=\int_{\mathbb R^3} dx\ e^{ikx}(1-u(|x|))v(|x|)
+ =\hat v(k)-\hat u\hat\ast\hat v(k)
+ ,\quad
+ \hat f\hat\ast\hat g(|k|):=\int_{\mathbb R^3}\frac{dp}{(2\pi)^3}\ \hat f(|k-p|)\hat g(|p|)
+ .
+\end{equation}
+We write this as a quadratic equation for $\hat u$, and solve it, keeping the solution that decays as $|k|\to\infty$:
+\begin{equation}
+ \rho\hat u(|k|)=
+ \frac{A_K(|k|)}{A_L(|k|)}\left(\xi(|k|)+1-\sqrt{(\xi(|k|)+1)^2-\frac{A_L(|k|)}{A_K^2(|k|)}\hat S(|k|)}\right)
+\end{equation}
+that is,
+\begin{equation}
+ \rho\hat u(|k|)=
+ \frac{\hat S(|k|)}{2A_K(|k|)(\xi(|k|)+1)}\Phi\left({\textstyle\frac{A_L(|k|)}{A_K^2(|k|)}\frac{\hat S(|k|)}{(\xi(|k|)+1)^2}}\right)
+ \label{uk_easyeq}
+\end{equation}
+with
+\begin{equation}
+ \xi(|k|):=\frac{k^2}{2\rho\hat A_K}
+ ,\quad
+ \Phi(x):=\frac{2(1-\sqrt{1-x})}x
+ .
+\end{equation}
+Furthermore, using bipolar coordinates (see lemma\-~\ref{lemma:bipolar}), we write $\hat S$ as
+\begin{equation}
+ \hat S(|k|)=\hat v(|k|)-\frac1{8\pi^3}\int_0^\infty dt\ t\hat u(t)\Eta(|k|,t)
+ ,\quad
+ \Eta(y,t):=\frac{2\pi}y\int_{|y-t|}^{y+t}ds\ s\hat v(s)
+ .
+ \label{easyeq_Eta}
+\end{equation}
+By a simple change of variables,
+\begin{equation}
+ \Eta(y,t)=
+ 4\pi\left(\mathds 1_{y>t}\frac{t}y+\mathds 1_{y\leqslant t}\right)
+ \int_0^1 ds\ ((y+t)s+|y-t|(1-s))v((y+t)s+|y-t|(1-s))
+ .
+ \label{Eta}
+\end{equation}
+\bigskip
+
+\point{\bf Evaluating integrals.}
+To compute these integrals numerically, we will use Gauss-Legendre quadratures:
+\begin{equation}
+ \int_0^1 dt\ f(t)\approx\frac12\sum_{i=1}^N w_if\left({\textstyle\frac{r_i+1}2}\right)
+\end{equation}
+where $w_i$ and $r_i$ are the Gauss-Legendre {\it weights} and {\it abcissa}.
+The order $N$ corresponds to the parameter \refname{param:easyeq_order}{{\tt order}}.
+The error made by the quadrature is estimated in appendix\-~\ref{appGL}.
+We compactify the integrals to the interval $(0,1)$: $y:=\frac1{t+1}$:
+\begin{equation}
+ \hat S(|k|)=\hat v(|k|)-\frac1{8\pi^3}\int_0^1 dy\ \frac{(1-y)\hat u(\frac{1-y}y)\Eta(|k|,\frac{1-y}y)}{y^3}
+\end{equation}
+so, using the Gauss-Legendre quadrature, we approximate
+\begin{equation}
+ \hat S(|k|)\approx\hat v(|k|)-\frac1{16\pi^3}\sum_{j=1}^N w_j \frac{(1-y_j)\hat u(\frac{1-y_j}{y_j})\Eta(|k|,\frac{1-y_j}{y_j})}{y_j^3}
+ ,\quad
+ y_j:=\frac{r_j+1}2
+ .
+\end{equation}
+This suggests a natural discretization of Fourier space: let
+\begin{equation}
+ k_i:=\frac{1-r_i}{1+r_i}\equiv\frac{1-y_i}{y_i}
+ .
+ \label{easyeq_ki}
+\end{equation}
+Thus, defining
+\begin{equation}
+ \mathbb U_i:=\rho\hat u(k_i)
+ ,\quad
+ \hat v_i:=\hat v(k_i)
+\end{equation}
+and approximate\-~(\ref{uk_easyeq}):
+\begin{equation}
+ \mathbb U_i=\frac{\mathbb T_i}{2(\mathbb X_i+1)}\Phi\left({\textstyle\mathbb B_i\frac{\mathbb T_i}{(\mathbb X_i+1)^2}}\right)
+ \label{bbU_easyeq}
+\end{equation}
+with
+\begin{equation}
+ \mathbb A_{K,i}:=\beta_K\mathbb S_i+(1-\beta_K)\mathbb E
+ ,\quad
+ \mathbb B_{i}:=\frac{\beta_L\mathbb S_i+(1-\beta_L)\mathbb E}{\mathbb A_{K,i}}
+ ,\quad
+ \mathbb T_i:=\frac{\mathbb S_i}{\mathbb A_{K,i}}
+\end{equation}
+\begin{equation}
+ \mathbb S_i:=\hat v_i-\frac1{16\pi^3\rho}\sum_{j=1}^N w_j\frac{(1-y_j)\mathbb U_j\Eta(k_i,k_j)}{y_j^3}
+ ,\quad
+ \mathbb E:=\hat v(0)-\frac1{16\pi^3\rho}\sum_{j=1}^N w_j\frac{(1-y_j)\mathbb U_j\Eta(0,k_j)}{y_j^3}
+\end{equation}
+\begin{equation}
+ \mathbb X_i:=\frac{k_i^2}{2\rho\mathbb A_{K,i}}
+ .
+\end{equation}
+This is a discrete equation for the vector $(\mathbb U_i)_{i=1}^N$.
+\bigskip
+
+\point{\bf Main algorithm to compute $\mathbb U$.}\par\penalty10000
+\medskip\penalty10000
+\subpoint
+We rewrite\-~(\ref{bbU_easyeq}) as a root finding problem:
+\begin{equation}
+ \Xi_i(\mathbb U):=\mathbb U_i-\frac{\mathbb T_i}{2(\mathbb X_i+1)}\Phi\left({\textstyle B_i\frac{\mathbb T_i}{(\mathbb X_i+1)^2}}\right)
+ =0
+ \label{root_easyeq}
+\end{equation}
+which we solve using the Newton algorithm, that is, we define a sequence of $\mathbb U$'s:
+\begin{equation}
+ \mathbb U^{(n+1)}=\mathbb U^{(n)}-(D\Xi(\mathbb U^{(n)}))^{-1}\Xi(\mathbb U^{(n)})
+\end{equation}
+where $D\Xi$ is the Jacobian of $\Xi$:
+\begin{equation}
+ (D\Xi)_{i,j}:=\frac{\partial\Xi_i}{\partial\mathbb U_j}
+ .
+\end{equation}
+\bigskip
+
+\subpoint
+For small values of $\rho$, we initialize the algorithm with the hardcore scattering solution
+\begin{equation}
+ \hat u_0(k)=\frac{4\pi a_0}{k^2}
+ \label{easyeq_init}
+\end{equation}
+where $a_0$ is the scattering length of the potential $v$ (or an approximation thereof, which need not be very good).
+Thus,
+\begin{equation}
+ \mathbb U^{(0)}_i=\frac{4\pi a_0}{k_i^2}
+ .
+\end{equation}
+This is a good approximation for small $\rho$.
+For larger $\rho$, we choose $\mathbb U^{(0)}$ as the solution of {\tt easyeq} for a slightly smaller $\rho$, and proceed inductively (using the parameters \refname{param:easyeq_minlrho_init}{{\tt minlrho\_init}} and \refname{param:easyeq_nlrho_init}{{\tt nlrho\_init}}).
+\bigskip
+
+\subpoint
+We are left with computing the Jacobian of $\Xi$:
+\begin{equation}
+ \begin{largearray}
+ \frac{\partial\Xi_i}{\partial\mathbb U_j}
+ =\delta_{j,i}
+ -\frac1{2(\mathbb X_i+1)}\left(
+ \partial_j\mathbb T_i-\frac{\mathbb T_i\partial_j\mathbb X_i}{\mathbb X_i+1}
+ \right)\Phi\left({\textstyle\mathbb B_i\frac{\mathbb T_i}{(\mathbb X_i+1)^2}}\right)
+ \\[0.5cm]\hfill
+ -\frac{\mathbb T_i}{2(\mathbb X_i+1)^3}\left(
+ \mathbb B_i\partial_j\mathbb T_i+\mathbb T_i\partial_j\mathbb B_i-2\frac{\mathbb B_i\mathbb T_i\partial_j\mathbb X_i}{\mathbb X_i+1}
+ \right)\partial\Phi\left({\textstyle\mathbb B_i\frac{\mathbb T_i}{(\mathbb X_i+1)^2}}\right)
+ \end{largearray}
+ \label{jacobian_easyeq}
+\end{equation}
+with
+\begin{equation}
+ \partial_j\mathbb B_i=
+ (\beta_L(1-\beta_K)-\beta_K(1-\beta_L))
+ \frac{\mathbb E\partial_j\mathbb S_i-\mathbb S_i\partial_j\mathbb E}{(\beta_K\mathbb S_i+(1-\beta_K)\mathbb E)^2}
+\end{equation}
+\begin{equation}
+ \partial_j\mathbb T_i=
+ (1-\beta_K)\frac{\mathbb E\partial_j\mathbb S_i-\mathbb S_i\partial_j\mathbb E}{(\beta_K\mathbb S_i+(1-\beta_K)\mathbb E)^2}
+ ,\quad
+ \partial_j\mathbb A_{K,i}=\beta_K\partial_j\mathbb S_i+(1-\beta_K)\partial_j\mathbb E
+\end{equation}
+\begin{equation}
+ \partial_j\mathbb S_i:=-\frac1{16\pi^3\rho}w_j\frac{(1-y_j)\Eta(k_i,k_j)}{y_j^3}
+ ,\quad
+ \partial_j\mathbb E:=-\frac1{16\pi^3\rho}\sum_{j=1}^N w_j\frac{(1-y_j)\Eta(0,k_j)}{y_j^3}
+\end{equation}
+\begin{equation}
+ \partial_j\mathbb X_i:=-\frac{k_i^2}{2\rho\mathbb A_{K,i}^2}\partial_j\mathbb A_{K,i}
+ .
+\end{equation}
+\bigskip
+
+\subpoint
+We iterate the Newton algorithm until the Newton relative error $\epsilon$ becomes smaller than the \refname{param:easyeq_tolerance}{{\tt tolerance}} parameter.
+The Newton error is defined as
+\begin{equation}
+ \epsilon=\frac{\|\mathbb U^{(n+1)}-\mathbb U^{(n)}\|_2}{\|\mathbb U^{(n)}\|_2}
+\end{equation}
+where $\|\cdot\|_2$ is the $l_2$ norm.
+The energy thus obtained is
+\begin{equation}
+ e=\frac\rho2\mathds E
+\end{equation}
+the Fourier transform $\hat u$ of the solution is
+\begin{equation}
+ \hat u(k_i)\approx\frac{\mathbb U_i}\rho
+\end{equation}
+and the solution $u$ in real space is obtained by inverting the Fourier transform
+\begin{equation}
+ \begin{array}{>\displaystyle r@{\ }>\displaystyle l}
+ u(|x|)=\int\frac{dk}{8\pi^3}\ e^{-ikx}\hat u(|k|)
+ =&\frac1{2\pi^2|x|}\int_0^1dy\ \frac{(1-y)\sin(|x|\frac{1-y}y)\hat u(\frac{1-y}y)}{y^3}
+ \\[0.5cm]
+ \approx&
+ \frac1{4\pi^2|x|}\sum_{j=1}^Nw_j (1+k_j)^2k_j\sin(|x|k_j)\hat u(k_j)
+ .
+ \end{array}
+ \label{ux}
+\end{equation}
+To compute $2u-\rho u\ast u$, we replace $\hat u$ with $2\hat u-\rho\hat u^2$ in the previous equation.
+\bigskip
+
+\point{\bf Condensate fraction.}
+Finally, to compute the uncondensed fraction, we solve the modified {\tt easyeq} (see\-~\cite{CJL20b})
+\begin{equation}
+ (-\Delta+2\mu)u_\mu=v(1-u_\mu)-2\rho K+\rho^2L
+ \label{easyeq_mu}
+\end{equation}
+where $K$ and $L$ are defined as in\-~(\ref{easyeq_KL})-(\ref{easyeq_Se}) in which $u$ is replaced with $u_\mu$.
+The uncondensed fraction is then
+\begin{equation}
+ \eta=\partial_\mu e|_{\mu=0}
+ =-\frac\rho2\int dx\ v(|x|)\partial_\mu u_\mu(|x|)|_{\mu=0}
+ .
+\end{equation}
+To compute the energy in the presence of the parameter $\mu$, we proceed in the same way as for $\mu=0$, the only difference being that $k^2$ should formally be replaced by $k^2+2\mu$.
+In other words, we consider $\mathbb U_i=u_\mu(|k_i|)$ and define $\Xi(\mathbb U,\mu)$ in the same way as in\-~(\ref{root_easyeq}), except that $\mathbb X_i$ should be replaced by
+\begin{equation}
+ \frac{k_i^2+2\mu}{2\rho\mathbb A_{K,i}}
+ .
+\end{equation}
+We then solve
+\begin{equation}
+ \Xi(\mathbb U,\mu)=0
+ .
+\end{equation}
+By differentiating this identity with respect to $\mu$, we find $\partial_\mu u_\mu$:
+\begin{equation}
+ D\Xi\partial_\mu \mathbb U=-\partial_\mu\Xi
+\end{equation}
+and the uncondensed fraction is
+\begin{equation}
+ \eta
+ =\frac12\int dx\ v(x)(D\Xi)^{-1}\partial_\mu\Xi|_{\mu=0}
+\end{equation}
+thus
+\begin{equation}
+ \eta=\frac1{16\pi^3}\int_0^1 dy\ \frac{(1-y)\Eta(0,\frac{1-y}y)(D\Xi)^{-1}\partial_\mu\Xi|_{\mu=0}(\frac{1-y}y)}{y^3}
+\end{equation}
+which we approximate using a Gauss-Legendre quadrature:
+\begin{equation}
+ \eta\approx\frac1{32\pi^3}\sum_{j=1}^N w_j(1-k_j)^2k_j\Eta(0,k_j)\sum_{i=1}^N(D\Xi)^{-1}_{j,i}\partial_\mu\Xi_i|_{\mu=0}
+ .
+ \label{eta_easyeq}
+\end{equation}
+We then compute, using\-~(\ref{jacobian_easyeq}),
+\begin{equation}
+ \partial_\mu\Xi_i|_{\mu=0}
+ =
+ \frac{\mathbb T_i}{2\rho\mathbb A_{K,i}(\mathbb X_i+1)^2}\Phi\left({\textstyle\mathbb B_i\frac{\mathbb T_i}{(\mathbb X_i+1)^2}}\right)
+ +\frac{\mathbb B_i\mathbb T_i^2}{\rho\mathbb A_{K,i}(\mathbb X_i+1)^4}\partial\Phi\left({\textstyle\mathbb B_i\frac{\mathbb T_i}{(\mathbb X_i+1)^2}}\right)
+ .
+\end{equation}
+
+\subsection{\tt anyeq}\label{sec:anyeq}
+\indent
+This method is used to solve any of the equations in the Simplified approach.
+Specifically, it solves the equation
+\begin{equation}
+ -\Delta u
+ =
+ v(1-u)-2\rho K+\rho^2 L
+ \label{anyeq}
+\end{equation}
+with
+\begin{equation}
+ K=\gamma_K(1-\alpha_Ku)\left(\beta_K u\ast S+(1-\beta_K)\frac{2e}\rho u\right)
+ \label{anyeq_K}
+\end{equation}
+and
+\begin{equation}
+ L:=L_1+L_2+L_3
+\end{equation}
+\begin{equation}
+ L_1:=(1-\alpha_{L,1}u)\left(\beta_{L,1}u\ast u\ast S+(1-\beta_{L,1})\frac{2e}\rho u\ast u\right)
+\end{equation}
+\begin{equation}
+ L_2:=-\gamma_{L,2}(1-\alpha_{L,2}u)\left(\beta_{L,2}2u\ast(u(u\ast S))+(1-\beta_{L,2})\frac{4e}\rho u\ast u^2\right)
+\end{equation}
+\begin{equation}
+ L_3:=\gamma_{L,3}(1-\alpha_{L,3}u)\left(\beta_{L,3}\frac12\int dydz\ u(y)u(z-x)u(z)u(y-x)S(z-y)+(1-\beta_{L,3})\frac e\rho u^2\ast u^2\right)
+\end{equation}
+\begin{equation}
+ e=\frac\rho2\int dx\ (1-u(|x|))v(|x|)
+ .
+ \label{anyeq_e}
+\end{equation}
+The parameters $\alpha_\cdot$, $\beta_\cdot$ and $\gamma_\cdot$ can be set to turn\-~(\ref{anyeq}) into any of the approximations of the Simplified approach.
+For ease of use, there are several predefined equations, given in the following table.
+\bigskip
+
+\def\arraystretch{1.5}
+\setlength\tabcolsep{5pt}
+\makelink{table:anyeq_eqs}{}
+\hfil\begin{tabular}{|r|c|c|c|c|c|c|c|c|c|c|c|c|}
+ \hline
+ &$\alpha_K$ &$\beta_K$ &$\gamma_K$ &$\alpha_{L,1}$ &$\beta_{L,1}$ &$\alpha_{L,2}$ &$\beta_{L,2}$ &$\gamma_{L,2}$ &$\alpha_{L,3}$ &$\beta_{L,3}$ &$\gamma_{L,3}$\\
+ \hline
+ \makelink{eq:anyeq_compleq}{}{\tt compleq}&1&1&1&1&1&1&1&1&1&1&1\\
+ \makelink{eq:anyeq_bigeq}{} {\tt bigeq }&1&1&1&1&1&1&1&1&-&-&0\\
+ \makelink{eq:anyeq_fulleq}{} {\tt fulleq }&1&1&1&1&1&1&1&1&1&0&1\\
+ \makelink{eq:anyeq_medeq}{} {\tt medeq }&0&1&1&0&1&-&-&0&-&-&0\\
+ \makelink{eq:anyeq_simpleq}{}{\tt simpleq}&0&0&1&0&0&-&-&0&-&-&0\\
+ \hline
+\end{tabular}
+\bigskip
+
+Note that there is no $\gamma_{L,1}$, whose computation would be rather different.
+Note, in addition, that {\tt simpleq} and {\tt medeq} coincide with their definitions in\-~(\ref{easyeq}).
+The method used to solve this equation is very different from \refname{sec:easyeq}{{\tt easyeq}}, and is significantly longer to run.
+\bigskip
+
+\subsubsection{Usage}
+\indent
+Unless otherwise noted, this method takes the following parameters (specified via the {\tt [-p params]} flag, as a `{\tt;}' separated list of entries).
+\begin{itemize}
+ \item\makelink{param:anyeq_rho}{}
+ {\tt rho} ({\tt Float64}, default: $10^{-6}$): density $\rho$.
+
+ \item\makelink{param:anyeq_tolerance}{}
+ {\tt tolerance} ({\tt Float64}, default: $10^{-11}$): maximal size of final step in Newton iteration.
+
+ \item\makelink{param:anyeq_maxiter}{}
+ {\tt maxiter} ({\tt Int64}, default: 21): maximal number of iterations of the Newton algorithm before giving up.
+
+ \item\makelink{param:anyeq_P}{}
+ {\tt P} ({\tt Int64}, default: 11): order of all Chebyshev polynomial expansions (denoted by $P$ below).
+
+ \item\makelink{param:anyeq_N}{}
+ {\tt N} ({\tt Int64}, default: 12): order of all Gauss quadratures (denoted by $N$ below).
+
+ \item\makelink{param:anyeq_J}{}
+ {\tt J} ({\tt Int64}, default: 10): number of splines (denoted by $J$ below).
+
+ \item\makelink{param:anyeq_minlrho_init}{}
+ {\tt minlrho\_init} ({\tt Float64}, default: \refname{param:anyeq_rho}{{\tt rho}}): we initialize the Newton algorithm using the solution of \refname{eq:easyeq_medeq}{{\tt medeq}}, computed using the methods in \refname{sec:easyeq}{{\tt easyeq}}. This option is passed to the underlying \refname{sec:easyeq}{{\tt easyeq}} routine.
+
+ \item\makelink{param:anyeq_nlrho_init}{}
+ {\tt nlrho\_init} ({\tt Int64}, default: 1): this option is passed to the underlying \refname{sec:easyeq}{{\tt easyeq}} routine to initialize the Newton algorithm.
+
+ \item\makelink{param:anyeq_aK}{}
+ {\tt aK}, {\tt bK}, {\tt gK}, {\tt aL1}, {\tt bL1}, {\tt aL2}, {\tt bL2}, {\tt gL2}, {\tt aL3}, {\tt bL3}, {\tt gL3} ({\tt Float64}, default: 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0): the values of $\alpha_K$, $\beta_K$, $\gamma_K$, $\alpha_{L,1}$, $\beta_{L,1}$, $\alpha_{L,2}$, $\beta_{L,2}$, $\gamma_{L,2}$, $\alpha_{L,3}$, $\beta_{L,3}$, $\gamma_{L,3}$.
+
+ \item\makelink{param:anyeq_eq}{}
+ {\tt eq} ({\tt String}, default: ``{\tt bigeq}'', acceptable values: ``{\tt compleq}'', ``{\tt bigeq}'', ``{\tt fulleq}'', ``{\tt medeq}'', ``{\tt simpleq}''): A shortcut to select any of the equations defined in the \refname{table:anyeq_eqs}{table above}. When this option is set, none of
+ \refname{param:anyeq_aK}{\tt aK}, \refname{param:anyeq_aK}{\tt bK}, \refname{param:anyeq_aK}{\tt gK}, \refname{param:anyeq_aK}{\tt aL1}, \refname{param:anyeq_aK}{\tt bL1}, \refname{param:anyeq_aK}{\tt aL2}, \refname{param:anyeq_aK}{\tt bL2}, \refname{param:anyeq_aK}{\tt gL2}, \refname{param:anyeq_aK}{\tt aL3}, \refname{param:anyeq_aK}{\tt bL3}, \refname{param:anyeq_aK}{\tt gL3} should be set.
+\end{itemize}
+\bigskip
+
+The available {\tt commands} are the following.
+
+\begin{itemize}
+ \item\makelink{command:anyeq_energy}{}
+ {\tt energy}: compute the energy $e$ at a given $\rho$.\par
+ \underline{Output}: [$e$] [Newton error $\epsilon$].
+
+ \item\makelink{command:anyeq_energy_rho}{}
+ {\tt energy\_rho}: compute the energy $e$ as a function of $\rho$.
+ The Newton algorithm is initialized with the solution of \refname{eq:easyeq_medeq}{{\tt medeq}}.\par
+ \underline{Disabled parameters}: \refname{param:anyeq_rho}{{\tt rho}}, \refname{param:anyeq_minlrho_init}{{\tt minlrho\_init}} and \refname{param:anyeq_nlrho_init}{{\tt nlrho\_init}}.\par
+ \underline{Extra parameters}:
+ \begin{itemize}
+ \item\makelink{param:anyeq_minlrho}{}
+ {\tt minlrho} ({\tt Float64}, default: $10^{-6}$): minimal value for $\log_{10}\rho$.
+
+ \item\makelink{param:anyeq_maxlrho}{}
+ {\tt maxlrho} ({\tt Float64}, default: $10^{2}$): maximal value for $\log_{10}\rho$.
+
+ \item\makelink{param:anyeq_nlrho}{}
+ {\tt nlrho} ({\tt Int64}, default: $100$): number of values for $\rho$ (spaced logarithmically).
+
+ \item\makelink{param:anyeq_rhos}{}
+ {\tt rhos} ({\tt Array\{Float64\}}, default: $(10^{{\tt minlrho}+\frac{{\tt maxlrho}-{\tt minlrho}}{{\tt nlrho}}n})_n$: list of values for $\rho$, specified as a `{\tt,}' separated list.
+ \end{itemize}
+ \underline{Output} (one line for each value of $\rho$): [$\rho$] [$e$] [Newton error $\epsilon$].\par
+ \underline{Multithread support}: yes, different values of $\rho$ split up among workers.
+
+ \item\makelink{command:anyeq_energy_rho_init_prevrho}{}
+ {\tt energy\_rho\_init\_prevrho}: compute the energy $e$ as a function of $\rho$.
+ The Newton algorithm is initialized with the solution of \refname{eq:easyeq_medeq}{{\tt medeq}} for the lowest $\rho$, and with the previously computed $\rho$ for the larger densities.\par
+ \underline{Disabled parameters}: same as \refname{command:anyeq_energy_rho}{{\tt energy\_rho}}.\par
+ \underline{Extra parameters}: same as \refname{command:anyeq_energy_rho}{{\tt energy\_rho}}.\par
+ \underline{Output} (one line for each value of $\rho$): [$\rho$] [$e$] [Newton error $\epsilon$].
+
+ \item\makelink{command:anyeq_energy_rho_init_nextrho}{}
+ {\tt energy\_rho\_init\_nextrho}: same as \refname{command:anyeq_energy_rho_init_prevrho}{{\tt energy\_rho\_init\_prevrho}} except that the energy is computed for decreasing densities instead of increasing ones.
+ The Newton algorithm is initialized with the solution of \refname{eq:easyeq_medeq}{{\tt medeq}} for the largest $\rho$, and with the previously computed $\rho$ for the smaller densities.\par
+ \underline{Disabled parameters}: same as \refname{command:anyeq_energy_rho}{{\tt energy\_rho}}.\par
+ \underline{Extra parameters}: same as \refname{command:anyeq_energy_rho}{{\tt energy\_rho}}.\par
+ \underline{Output} (one line for each value of $\rho$): [$\rho$] [$e$] [Newton error $\epsilon$].
+
+ \item\makelink{command:anyeq_condensate_fraction}{}
+ {\tt condensate\_fraction}: compute the uncondensed fraction $\eta$ at a given $\rho$.\par
+ \underline{Output}: [$\eta$] [Newton error $\epsilon$].
+
+ \item\makelink{command:anyeq_condensate_fraction_rho}{}
+ {\tt condensate\_fraction\_rho}: compute the uncondensed fraction $\eta$ as a function of $\rho$.
+ The Newton algorithm is initialized with the solution of \refname{eq:easyeq_medeq}{{\tt medeq}}.\par
+ \underline{Disabled parameters}: same as \refname{command:anyeq_energy_rho}{{\tt energy\_rho}}.\par
+ \underline{Extra parameters}: same as \refname{command:anyeq_energy_rho}{{\tt energy\_rho}}.\par
+ \underline{Output} (one line for each value of $\rho$): [$\rho$] [$\eta$] [Newton error $\epsilon$].\par
+ \underline{Multithread support}: yes, different values of $\rho$ split up among workers.
+
+ \item\makelink{command:anyeq_uk}{}
+ {\tt uk}: compute the Fourier transform $\hat u(|k|)$.
+ The values $|k|$ at which $\hat u$ is computed are those coming from the Gauss quadratures, and cannot be set.\par
+ \underline{Output} (one line for each value of $|k|$): [$|k|$] [$\hat u(|k|)$]
+
+ \item\makelink{command:anyeq_ux}{}
+ {\tt ux}: compute $u$ as a function of $|x|$.\par
+ \underline{Extra parameters}:
+ \begin{itemize}
+ \item\makelink{param:anyeq_xmin}{}
+ {\tt xmin} ({\tt Float64}, default: 0): minimum of the range of $|x|$ to be printed.
+
+ \item\makelink{param:anyeq_xmax}{}
+ {\tt xmax} ({\tt Float64}, default: 100): maximum of the range of $|x|$ to be printed.
+
+ \item\makelink{param:anyeq_nx}{}
+ {\tt nx} ({\tt Int64}, default: 100): number of points to print (linearly spaced).
+
+ \end{itemize}
+ \underline{Output} (one line for each value of $x$): [$|x|$] [$\mathcal Re(u(|x|))$] [$\mathcal Im(u(|x|))$]
+
+ \item\makelink{command:anyeq_momentum_distribution}{}
+ {\tt momentum\_distribution}: compute the momentum distribution $\mathfrak M(|k|)$ at a given $\rho$.\par
+ \underline{Output} (one line for each value of $|k|$): [$|k|$] [$\mathfrak M(|k|)$]
+
+ \item\makelink{command_anyeq_2pt}{}
+ {\tt 2pt}: compute the two-point correlation function $C_2(|x|)$ at a given $\rho$.\par
+ \underline{Extra parameters}: same as \refname{command:anyeq_ux}{{\tt ux}}, plus\par
+ \begin{itemize}
+ \item\makelink{param:anyeq_window_L}{}
+ {\tt window\_L} ({\tt Float64}, default: $10^3$): size of the Hann window used to numerically invert the Fourier transform in the computation of the tow-point correlation function, see\-~(\ref{hann}).
+ \end{itemize}
+ \underline{Output} (one line for each value of $|x|$): [$|x|$] [$C_2(|x|)$]
+
+ \item \makelink{command:anyeq_save_Abar}{}
+ {\tt save\_Abar}: compute the matrix $\bar A$. This matrix is used to compute observables for \refname{eq:anyeq_compleq}{{\tt compleq}}. This command is useful to output the value of $\bar A$ to a file once and for all, and use this file to run commands without recomputing $\bar A$.\par
+ \underline{Disabled parameters}: \refname{param:anyeq_rho}{{\tt rho}}, \refname{param:anyeq_tolerance}{{\tt tolerance}}, \refname{param:anyeq_maxiter}{{\tt maxiter}}, \refname{param:anyeq_minlrho_init}{{\tt minlrho\_init}}, \refname{param:anyeq_nlrho}{{\tt nlrho}}.\par
+ \underline{Output}: [$\bar A$] (the output is not designed to be human-readable; it is obtained through nested {\tt for} loops; for details, see the code).\par
+ \underline{Multithread support}: yes, the first indices are split up among workers, which produces $NJ$ jobs.
+
+\end{itemize}
+
+\subsubsection{Description}
+\point{\bf Fourier space formulation.}
+The computation is carried out in Fourier space.
+We take the convention that the Fourier transform of a function $f(|x|)$ is
+\begin{equation}
+ \hat f(|k|)=\int_{\mathbb R^3} dx\ e^{ikx}f(|x|)
+ =\frac{4\pi}{|k|}\int_0^\infty dr\ \frac{\sin(|k|r)}rf(r)
+ .
+ \label{anyeq_fourier}
+\end{equation}
+We define a Fourier-space convolution:
+\begin{equation}
+ \hat f\hat\ast\hat g(|k|):=\int_{\mathbb R^3}\frac{dp}{(2\pi)^3}\ \hat f(|k-p|)\hat g(|p|)
+ .
+ \label{anyeq_hatast}
+\end{equation}
+In Fourier space, (\ref{anyeq}) becomes
+\begin{equation}
+ k^2\hat u(|k|)=\hat S(|k|)-2\rho\hat K(|k|)+\rho^2\hat L(|k|)
+\end{equation}
+with
+\begin{equation}
+ \hat S(|k|)=\int_{\mathbb R^3} dx\ e^{ikx}(1-u(|x|))v(|x|)
+ =\hat v(k)-\hat u\hat\ast\hat v(k)
+\end{equation}
+\begin{equation}
+ \rho\hat K=
+ \gamma_K(\beta_K\rho\hat S+(1-\beta_K)2e)\hat u
+ -
+ \gamma_K\alpha_K\hat u\hat\ast((\beta_K\rho\hat S+(1-\beta_K)2e)\hat u)
+\end{equation}
+\begin{equation}
+ \rho\hat L_1=
+ (\beta_{L,1}\rho\hat S+(1-\beta_{L,1})2e)\hat u^2
+ -
+ \alpha_{L,1}\hat u\hat\ast((\beta_{L,1}\rho\hat S+(1-\beta_{L,1})2e)\hat u^2)
+\end{equation}
+\begin{equation}
+ \rho\hat L_2=
+ -\gamma_{L,2}(\beta_{L,2}2\rho(\hat u\hat\ast(\hat u\hat S))+(1-\beta_{L,2})4e\hat u\hat\ast\hat u)\hat u
+ +
+ \gamma_{L,2}\alpha_{L,2}\hat u\hat\ast((\beta_{L,2}2\rho(\hat u\hat\ast(\hat u\hat S))+(1-\beta_{L,2})4e\hat u\hat\ast\hat u)\hat u)
+\end{equation}
+\begin{equation}
+ \rho\hat L_3=
+ \gamma_{L,3}(1-\beta_{L,3})e(\hat u\hat\ast\hat u)^2
+ -
+ \gamma_{L,3}\alpha_{L,3}(1-\beta_{L,3})\hat u\hat\ast(e(\hat u\hat\ast\hat u)^2)
+ +
+ \gamma_{L,3}\beta_{L,3}\hat l_3
+ -
+ \frac1{2\rho}\gamma_{L,3}\alpha_{L,3}\beta_{L,3}\hat u\hat\ast\hat l_3
+\end{equation}
+with
+\begin{equation}
+ \hat l_3(|k|):=
+ \frac1{\rho^2}\int\frac{dq}{(2\pi)^3}\frac{dq'}{(2\pi)^3}\ \rho\hat u(|k-q'|)\rho\hat u(|q|)\rho\hat u(|q'|)\rho\hat u(|k-q|)\hat S(|q'-q|)
+ \label{l3}
+\end{equation}
+Therefore,
+\begin{equation}
+ \rho^2\hat u(|k|)^2\sigma_{L,1}(|k|)
+ -\left(\frac{k^2}\rho+2\sigma_K(|k|)+2f_1(|k|)\right)\rho\hat u(|k|)
+ +\left(\hat S(|k|)+\frac12f_2(|k|)+G(|k|)\right)
+ =
+ 0
+\end{equation}
+with
+\begin{equation}
+ \sigma_K:=\frac1{\rho}\gamma_K(\beta_K\rho\hat S+(1-\beta_K)2e)
+ ,\quad
+ \sigma_{L,1}:=\frac1{\rho}(\beta_{L,1}\rho\hat S+(1-\beta_{L,1})2e)
+\end{equation}
+\begin{equation}
+ f_1:=\frac1{\rho^2}\gamma_{L,2}(\beta_{L,2}\rho(\rho\hat u\hat\ast(\rho\hat u\hat S))+(1-\beta_{L,2})2e\rho\hat u\hat\ast\rho\hat u)
+\end{equation}
+\begin{equation}
+ f_2:=\gamma_{L,3}(1-\beta_{L,3})\frac{2e}{\rho^3}(\rho\hat u\hat\ast\rho\hat u)^2
+ +\gamma_{L,3}\beta_{L,3}\hat l_3
+\end{equation}
+\begin{equation}
+ \begin{largearray}
+ G:=
+ \frac2{\rho^2}\gamma_K\alpha_K\rho\hat u\hat\ast((\beta_K\rho\hat S+(1-\beta_K)2e)\rho\hat u)
+ -
+ \frac1{\rho^2}\alpha_{L,1}\rho\hat u\hat\ast((\beta_{L,1}\rho\hat S+(1-\beta_{L,1})2e)\rho\hat u^2)
+ \\[0.5cm]\hfill
+ +
+ \frac2{\rho}\alpha_{L,2}\rho\hat u\hat\ast(f_1\rho\hat u)
+ -
+ \frac1{2\rho}\alpha_{L,3}\rho\hat u\hat\ast f_2
+ .
+ \end{largearray}
+\end{equation}
+Therefore,
+\begin{equation}
+ \rho\hat u=1+\xi
+ -\sqrt{(1+\xi)^2-(1+\zeta)}
+ \label{u}
+\end{equation}
+with
+\begin{equation}
+ \xi:=\frac1{\sigma_{L,1}}\left(\sigma_K-\sigma_{L,1}+\frac{k^2}{2\rho}+f_1\right)
+ ,\quad
+ \zeta:=\frac1{\sigma_{L,1}}\left(\hat S-\sigma_{L,1}+\frac12f_2+G\right)
+\end{equation}
+We rewrite\-~(\ref{u}) as
+\begin{equation}
+ U=
+ \frac{1+\zeta}{2(\xi+1)}\ \Phi\left({\textstyle\frac{1+\zeta}{(\xi+1)^2}}\right)
+ \label{anyeq_hatu}
+\end{equation}
+with
+\begin{equation}
+ U:=\rho\hat u
+\end{equation}
+\begin{equation}
+ \Phi(x):=\frac{2(1-\sqrt{1-x})}x
+ .
+\end{equation}
+\bigskip
+
+\point{\bf Evaluating integrals.}
+To evaluate integrals numerically, we will split integration intervals over splines and use Gauss-Legendre quadratures.
+More specifically, to compute integrals of the form
+\begin{equation}
+ \int \frac{dk}{(2\pi)^3}\ f(U(k),k)
+ =
+ \frac1{2\pi^2}\int_0^\infty dt\ t^2f(U(t),t)
+\end{equation}
+we first compactify space to $(-1,1]$ by changing variables to $\tau=\frac{1-t}{1+t}$:
+\begin{equation}
+ \int \frac{dk}{(2\pi)^3}\ f(U(k),k)
+ =
+ \frac1{\pi^2}\int_{-1}^1 d\tau\ \frac{(1-\tau)^2}{(1+\tau)^4}f({\textstyle U(\frac{1-\tau}{1+\tau}),\frac{1-\tau}{1+\tau}})
+ .
+\end{equation}
+We then split $(-1,1]$ into $J$ sub-intervals (given by the parameter \refname{param:anyeq_J}{{\tt J}}), called {\it splines}:
+\begin{equation}
+ (-1,1]=\bigcup_{j=0}^{J-1}(\tau_j,\tau_{j+1}]
+ .
+\end{equation}
+The $\tau$ are taken to be equally spaced, but the code is designed in such a way that this could be changed easily in the future:
+\begin{equation}
+ \tau_j=-1+\frac{2j}J
+ .
+\end{equation}
+In these terms,
+\begin{equation}
+ \int \frac{dk}{(2\pi)^3}\ f(U(k),k)
+ =
+ \sum_{l=0}^{J-1}
+ \int_{\tau_l}^{\tau_{l+1}} d\tau\ \frac{(1-\tau)^2}{(1+\tau^4}g(U({\textstyle\frac{1-\tau}{1+\tau},\frac{1-\tau}{1+\tau}})
+ .
+\end{equation}
+We then change variables to $r$:
+\begin{equation}
+ \tau=
+ -\frac{\tau_{l+1}-\tau_l}2\sin({\textstyle\frac{\pi r}2})+\frac{\tau_{l+1}+\tau_l}2
+ =:\frac{1-\vartheta_l(r)}{1+\vartheta_l(r)}
+ \label{chebyshevvars}
+\end{equation}
+(the reason for this specific change of variables will become clear at the end of this paragraph and in the next one)
+and find
+\begin{equation}
+ \int \frac{dk}{(2\pi)^3}\ f(U(k),k)
+ =
+ \sum_{l=0}^{J-1}
+ \frac{\tau_{l+1}-\tau_l}{16\pi}\int_{-1}^1 dr\ \cos({\textstyle\frac{\pi r}2})(1+\vartheta_l(r))^2\vartheta_l^2(r)f(U(\vartheta_l(r)),\vartheta_l(r))
+ .
+\end{equation}
+We then approximate the integral using a Gauss-Legendre quadrature of order $N$ (see appendix\-~\ref{appGL}):
+\begin{equation}
+ \int \frac{dk}{(2\pi)^3}\ f(k)
+ \approx
+ \sum_{l=0}^{J-1}
+ \frac{\tau_{l+1}-\tau_l}{16\pi}
+ \sum_{j=1}^Nw_j
+ \cos({\textstyle\frac{\pi x_j}2})(1+\vartheta_l(x_j))^2\vartheta_l^2(x_j)f(\mathbb U_{l,j},\vartheta_l(x_j))
+ \label{anyeq_integration}
+\end{equation}
+with
+\begin{equation}
+ \mathbb U_{l,j}:=U(k_{l,j})
+ ,\quad
+ k_{l,j}:=\frac{2+(\tau_{l+1}-\tau_l)\sin(\frac{\pi x_j}2)-(\tau_{l+1}+\tau_\alpha)}{2-(\tau_{l+1}-\tau_l)\sin(\frac{\pi x_j}2)+(\tau_{l+1}+\tau_l)}
+ .
+\end{equation}
+The choice of the change of variables\-~(\ref{chebyshevvars}) is made so that $U$ is evaluated at $k_{l,j}$, which are the momenta that appear naturally in the Chebyshev polynomial expansion below\-~(\ref{klj}).
+In this way, we can compute arbitrary integrals of functions of $U$ by just computing the values of $\mathbb U_{l,j}$.
+\bigskip
+
+\point{\bf Chebyshev polynomial expansion.}
+In the case of \refname{sec:easyeq}{{\tt easyeq}}, we saw that using Gauss quadratures reduced the computation to evaluating $U$ at a fixed set of discrete momenta.
+This is not the case here, due to the presence of more complicated convolutions of $U$.
+Instead, we will approximate $U$ using polynomial approximations.
+We will now discuss this approximation for an arbitrary function $a(|k|)$, as we will need it for other functions than simply $U$.
+\bigskip
+
+\subpoint
+As in the previous paragraph, we compactify $[0,\infty)$ to $(-1,1]$ via the change of variables $r\mapsto\frac{1-r}{1+r}$, and split the interval into splines.
+Inside each spline, we use a Chebyshev polynomial expansion.
+However, we need to be careful in the first spline, which encapsulates the behavior at $|k|\to\infty$: $U$ decays to 0 as $|k|\to\infty$, and this behavior cannot be reproduced by a polynomial expansion.
+To avoid this, if $a\sim|k|^{-\nu_a}$, we expand $|k|^{\nu_a}a$ instead of $a$.
+Actually, to simplify expressions in the presence of the compactification, we will expand $2^{-\nu_a}(1+|k|)^{\nu_a}a$, which makes no conceptual difference.
+In the case of $a=U$, we will use $\nu=2$, which we know holds for the Simple equation\-~\cite{CJL20}.
+Putting all this together, we write, for $\tau\in(-1,1]$, if $|k|\equiv\frac{1-\tau}{1+\tau}$,
+\begin{equation}
+ 2^{-\nu_a}(1+|k|)^{\nu_a}a(|k|)\equiv
+ \frac1{(1+\tau)^{\nu_a}}a({\textstyle\frac{1-\tau}{1+\tau}})
+ =\sum_{l=0}^{J-1}\mathds 1_{\tau_l<\tau\leqslant\tau_{l+1}}\sum_{n=0}^\infty \mathbf F_{l,n}^{(\nu_a)}(a) T_n({\textstyle\frac{2\tau-(\tau_l+\tau_{l+1})}{\tau_{l+1}-\tau_l}})
+ \label{a_chebyshev_spline}
+\end{equation}
+in which $\mathds 1_{\tau_l<\tau\leqslant\tau_{l+1}}\in\{0,1\}$ is equal to 1 if and only if $\tau_l<\tau\leqslant\tau_{l+1}$, and
+\begin{equation}
+ \mathbf F_{l,n}^{(\nu_a)}(a):=
+ \frac{2-\delta_{n,0}}{\pi}
+ \int_0^{\pi} d\theta\
+ \frac{\cos(n\theta)}{(1+\frac{\tau_{l+1}-\tau_l}2\cos(\theta)+\frac{\tau_{l+1}+\tau_l}2)^{\nu_a}}
+ a({\textstyle\frac{2-(\tau_{l+1}-\tau_l)\cos(\theta)-(\tau_{l+1}+\tau_\alpha)}{2+(\tau_{l+1}-\tau_l)\cos(\theta)+(\tau_{l+1}+\tau_l)}})
+ \label{bfF}
+\end{equation}
+(see appendix\-~\ref{appChebyshev} for a discussion of the Chebyshev polynomial expansion and the error of its truncations).
+\bigskip
+
+\subpoint
+In order to compute an approximation for $a$ using\-~(\ref{a_chebyshev_spline}), we will truncate the sum over $n$ to a finite value $P$ (given by the parameter \refname{param:anyeq_P}{{\tt P}}).
+In addition, to compute the integral in\-~(\ref{bfF}), we will use a Gauss-Legendre quadrature of order $N$ (given by the parameter \refname{param:anyeq_N}{{\tt N}}), see appendix\-~\ref{appGL}:
+\begin{equation}
+ \mathbf F_{l,n}^{(\nu_a)}(a)\approx\mathfrak F_{l,n}^{(\nu_a)}(\mathfrak a):=
+ \frac{2-\delta_{n,0}}2\sum_{j=1}^N w_j \cos({\textstyle\frac{n\pi(1+x_j)}2})\frac{\mathfrak a_{l,j}}{(1-\frac{\tau_{l+1}-\tau_l}2\sin(\frac{\pi x_j}2)+\frac{\tau_{l+1}+\tau_l}2)^{\nu_a}}
+ \label{frakF}
+\end{equation}
+with
+\begin{equation}
+ \mathfrak a_{l,j}:=a(k_{l,j})
+ ,\quad
+ k_{l,j}:=\frac{2+(\tau_{l+1}-\tau_l)\sin(\frac{\pi x_j}2)-(\tau_{l+1}+\tau_\alpha)}{2-(\tau_{l+1}-\tau_l)\sin(\frac{\pi x_j}2)+(\tau_{l+1}+\tau_l)}
+ \label{klj}
+\end{equation}
+and $(x_j,w_j)$ are the abcissa and weights for Gauss-Legendre quadratures.
+\bigskip
+
+\subpoint
+All in all, we approximate
+\begin{equation}
+ a({\textstyle\frac{1-\tau}{1+\tau}})
+ \approx(1+\tau)^{\nu_a}\sum_{l=0}^{J-1}\mathds 1_{\tau_l<\tau\leqslant\tau_{l+1}}\sum_{n=0}^P \mathfrak F_{l,n}^{(\nu_a)}(\mathfrak a) T_n({\textstyle\frac{2\tau-(\tau_l+\tau_{l+1})}{\tau_{l+1}-\tau_l}})
+ \label{approxchebyshev}
+\end{equation}
+with $\mathfrak F$ defined in\-~(\ref{frakF}).
+Furthermore, using the Chebyshev polynomial expansion and Gauss-Legendre quadratures, we can compute all the observables we are interested in by computing $\mathbb U_{l,j}\equiv U(k_{l,j})$.
+With this in mind, we will represent the function $U$ as a vector of dimension $NJ$ whose components are $\mathbb U_{l,j}$.
+\bigskip
+
+\point{\bf Convolutions.}
+Using the Chebyshev polynomial approximation, we can compute convolutions as follows.
+\medskip
+
+\subpoint
+First, we rewrite the convolution as a two-dimensional integral, using bipolar coordinates (see lemma\-~\ref{lemma:bipolar}):
+\begin{equation}
+ (a\hat\ast b)(|k|)=\frac1{4\pi^2|k|}\int_0^\infty dt\ ta(t)\int_{||k|-t|}^{|k|+t}ds\ sb(s)
+\end{equation}
+We change variables to compactify the integrals $\tau=\frac{1-t}{1+t}$, $\sigma=\frac{1-s}{1+s}$:
+\begin{equation}
+ (a\hat\ast b)(|k|)=\frac1{4\pi^2|k|}\int_{-1}^1 d\tau\ \frac{2(1-\tau)}{(1+\tau)^3}a({\textstyle\frac{1-\tau}{1+\tau}})\int_{\alpha_-(|k|,\tau)}^{\alpha_+(|k|,\tau)}d\sigma\ \frac{2(1-\sigma)}{(1+\sigma)^3}b({\textstyle\frac{1-\sigma}{1+\sigma}})
+ \label{convvar}
+\end{equation}
+with
+\begin{equation}
+ \alpha_-(|k|,\tau):=\frac{1-|k|-\frac{1-\tau}{1+\tau}}{1+|k|+\frac{1-\tau}{1+\tau}}
+ ,\quad
+ \alpha_+(|k|,\tau):=\frac{1-||k|-\frac{1-\tau}{1+\tau}|}{1+||k|-\frac{1-\tau}{1+\tau}|}
+ .
+ \label{anyeq_alpha}
+\end{equation}
+Therefore, using the approximation\-~(\ref{approxchebyshev}), if $\mathfrak a_{l,j}:=a(k_{l,j})$ and $\mathfrak b_{l,j}:=b(k_{l,j})$ (\ref{klj}),
+\begin{equation}
+ (a\hat\ast b)(|k_{l,j}|)\approx
+ (\mathfrak a\odot \mathfrak b)_{l,j}:=
+ \frac1{4\pi^2|k_{l,j}|}
+ \sum_{n,m=0}^P
+ \sum_{l,l'=0}^{J-1}
+ \mathfrak F_{l,n}^{(\nu_a)}(\mathfrak a)\mathfrak F_{l',m}^{(\nu_b)}(\mathfrak b)
+ A_{l,n;l',m}^{(\nu_a,\nu_b)}(|k_{l,j}|)
+ \label{odot}
+\end{equation}
+with
+\begin{equation}
+ \begin{largearray}
+ A_{l,n;l',m}^{(\nu_a,\nu_b)}(|k|):=
+ \int_{\tau_l}^{\tau_{l+1}} d\tau\ \frac{2(1-\tau)}{(1+\tau)^{3-\nu_a}}T_n({\textstyle\frac{2\tau-(\tau_l+\tau_{l+1})}{\tau_{l+1}-\tau_l}})
+ \cdot\\[0.5cm]\hfill\cdot
+ \mathds 1_{\alpha_-(|\tilde k|,\tau)<\tau_{\zeta'+1}}
+ \mathds 1_{\alpha_+(|\tilde k|,\tau)>\tau_{\zeta'}}
+ \int_{\max(\tau_{l'},\alpha_-(|k|,\tau))}^{\min(\tau_{l'+1},\alpha_+(|k|,\tau))}d\sigma\ \frac{2(1-\sigma)}{(1+\sigma)^{3-\nu_b}}T_m({\textstyle\frac{2\sigma-(\tau_{l'}+\tau_{l'+1})}{\tau_{l'+1}-\tau_{l'}}})
+ \end{largearray}
+\end{equation}
+(we need the indicator functions to ensure that the bounds of the integral are correct).
+Note that $A$ is independent of $a$ and $b$, and can be computed once and for all at the beginning of execution for all values of $k_{l,j}$ (\ref{klj}).
+We then compute the integrals using Gauss-Legendre quadratures (as is proved in the next paragraph, the integrand is non singular provided $\nu_a,\nu_b\geqslant 2$).
+\bigskip
+
+\subpoint
+Note that these integrals are not singular as long as $\nu_a,\nu_b\geqslant 2$: indeed (since the only possible problems occur at $-1$, it suffices to consider the case with only one spline), $\alpha_-,\alpha_+>-1$ for $\tau>-1$, and
+\begin{equation}
+ \alpha_\pm(k,\tau)=-1+(1+\tau)\pm\frac k2(1+\tau)^2+O(1+\tau)^3
+\end{equation}
+and
+\begin{equation}
+ \int_{\alpha_-(|k|,\tau)}^{\alpha_+(|k|,\tau)}d\sigma\ \left|\frac{2(1-\sigma)}{(1+\sigma)^{3-\nu_b}}T_m(\sigma)\right|
+ \leqslant
+ 4\int_{\alpha_-(|k|,\tau)}^{\alpha_+(|k|,\tau)}d\sigma\ \frac1{(1+\sigma)^{3-\nu_b}}
+\end{equation}
+which, if $\nu_b=2$, yields
+\begin{equation}
+ 4\log\left(\frac{1+\alpha_+(|k|,\tau)}{1+\alpha_-(|k|,\tau)}\right)
+ =4|k|(1+\tau)+O(1+\tau)^2
+\end{equation}
+and if $\nu_b>2$, yields
+\begin{equation}
+ \frac4{\nu_b-2}\left((1+\alpha_+(|k|,\tau))^{\nu_b-2}-(1+\alpha_-(|k|,\tau))^{\nu_b-2}\right)
+ =
+ \frac4{\nu_b-2}|k|(1+\tau)^{\nu_b-1}(1+O(1+\tau))
+ .
+\end{equation}
+Therefore,
+\begin{equation}
+ \left|\frac{2(1-\tau)}{(1+\tau)^{3-\nu_a}}T_n(\tau)\int_{\alpha_-(|k|,\tau)}^{\alpha_+(|k|,\tau)}d\sigma\ \frac{2(1-\sigma)}{(1+\sigma)^{3-\nu_b}}T_m(\sigma)\right|
+ \leqslant
+ \frac8{c_{\nu_b}}
+ |k|(1-\tau)(1+\tau)^{\nu_a+\nu_b-4}(1+O(1+\tau))
+\end{equation}
+where $c_{2}:=1$ and $c_{\nu_b}:=\nu_b-2$ if $\nu_b>2$.
+The integrand is, therefore, not singular as long as $\nu_a,\nu_b\geqslant 2$.
+\bigskip
+
+\subpoint
+Evaluating convolutions at $k=0$ is not immediate, as the formula for $A(0)$ involves a bit of a computation.
+To compute $A(0)$, we expand
+\begin{equation}
+ \alpha_-(|k|,\tau)=\tau-\frac{|k|(1+\tau)^2}2+O(k^2)
+ ,\quad
+ \alpha_+(|k|,\tau)=\tau+\frac{|k|(1+\tau)^2}2+O(k^2)
+\end{equation}
+so
+\begin{equation}
+ A_{\zeta,n;\zeta',m}^{(\nu_a,\nu_b)}(0)=\mathds 1_{\zeta=\zeta'}
+ \frac1{\pi^2}
+ \int_{\tau_\zeta}^{\tau_{\zeta+1}} d\tau\ \frac{(1-\tau)^2}{(1+\tau)^{4-\nu_a-\nu_b}}T_n({\textstyle\frac{2\tau-(\tau_\zeta+\tau_{\zeta+1})}{\tau_{\zeta+1}-\tau_\zeta}})
+ T_m({\textstyle\frac{2\tau-(\tau_{\zeta}+\tau_{\zeta+1})}{\tau_{\zeta+1}-\tau_{\zeta}}})
+\end{equation}
+which we then compute using a Gauss-Legendre quadrature.
+We can then evaluate convolutions at $k=0$:
+\begin{equation}
+ (a\hat\ast b)(0)\approx\left<\mathfrak a\mathfrak b\right>
+ :=
+ \frac1{4\pi^2|k_{l,j}|}
+ \sum_{n,m=0}^P
+ \sum_{l,l'=0}^{J-1}
+ \mathfrak F_{l,n}^{(\nu_a)}(\mathfrak a)\mathfrak F_{l',m}^{(\nu_b)}(\mathfrak b)
+ A_{l,n;l',m}^{(\nu_a,\nu_b)}(0)
+ \label{avg}
+\end{equation}
+\bigskip
+
+
+\subpoint
+Let us now compute some choices of $\mathfrak a,\mathfrak b$ more explicitly.
+\medskip
+
+\subsubpoint
+Let us start with $\mathds 1_{l,n}\hat\ast a$ where $\mathds 1_{l,n}$ is the vector which has 0's everywhere except at position $(l,n)$.
+We have
+\begin{equation}
+ \mathfrak F_{l',m}^{(\nu_1)}(\mathds 1_{l,n})=\delta_{l',l}\frac{2-\delta_{m,0}}2w_n\frac{\cos({\textstyle\frac{m\pi(1+x_n)}2})}{(1-\frac{\tau_{l+1}-\tau_l}2\sin(\frac{\pi x_j}2)+\frac{\tau_{l+1}+\tau_l}2)^{\nu_1}}
+\end{equation}
+so
+\begin{equation}
+ (\mathds 1_{n,l''}\odot\mathfrak a)_{m,l}=
+ \sum_{l,p}\sum_{l'}\frac{2-\delta_{l,0}}2w_n\frac{\cos({\textstyle\frac{l\pi(1+x_n)}2})}{(1-\frac{\tau_{l''+1}-\tau_{l''}}2\sin(\frac{\pi x_n}2)+\frac{\tau_{l''+1}+\tau_{l''}}2)^{\nu_1}}A_{l'',l;l',p}^{(\nu_1,\nu_a)}(k_{l,m})\mathfrak F_{l',p}^{(\nu_a)}(\mathfrak a)
+ .
+\end{equation}
+\bigskip
+
+\subsubpoint
+We now turn to $a\hat\ast\hat v$.
+Let
+\begin{equation}
+ \Upsilon(t,|k|):=
+ \int_{||k|-t|}^{|k|+t}ds\ \frac{s\hat v(s)}{|k|}
+ \label{Upsilon}
+\end{equation}
+We have
+\begin{equation}
+ a\hat\ast\hat v=\frac 1{4\pi^2}\int_0^\infty dt\ ta(t)\Upsilon(t,|k|)
+ .
+ \label{avUpsilon}
+\end{equation}
+Following the integration scheme\-~(\ref{anyeq_integration}),
+\begin{equation}
+ (\mathfrak a\odot\mathfrak v)_{l,i}=
+ \frac1{32\pi}\sum_{l'=0}^{J-1}(\tau_{l'+1}-\tau_{l'})\sum_{j=1}^Nw_j \cos({\textstyle\frac{\pi x_j}2})(1+\vartheta_{l'}(x_j))^2\vartheta_{l'}(x_j)\mathfrak a_{l',j}\Upsilon(\vartheta(x_j),k_{l,i})
+ .
+ \label{adotv}
+\end{equation}
+At $k=0$,
+\begin{equation}
+ \left<\mathfrak a\mathfrak v\right>=
+ \frac1{32\pi}\sum_{l'=0}^{J-1}(\tau_{l'+1}-\tau_{l'})\sum_{j=1}^Nw_j \cos({\textstyle\frac{\pi x_j}2})(1+\vartheta_{l'}(x_j))^2\vartheta_{l'}(x_j)\mathfrak a_{l',j}\Upsilon(\vartheta(x_j),0)
+ \label{<av>}
+\end{equation}
+with
+\begin{equation}
+ \Upsilon(t,0)=2tv(t)
+ .
+\end{equation}
+The quantities $\Upsilon(\vartheta(x_n),k_{l,i})$ and $\Upsilon(\vartheta(x_n),0)$ are independent of $a$ and can be computed once and for all at execution.
+The integral in\-~(\ref{Upsilon}) is computed using Gauss-Legendre quadratures, but without splitting into splines.
+To maintain a high precision, we set the order of the integration to \refname{param:anyeq_J}{{\tt J}}$\times$\refname{param:anyeq_N}{{\tt N}}.
+\bigskip
+
+\subsubpoint
+Finally,
+\begin{equation}
+ (\mathds 1_{l',n}\odot\mathfrak v)_{l,i}=
+ \frac{\tau_{l'+1}-\tau_{l'}}{32\pi}w_n\cos({\textstyle\frac{\pi x_n}2})(1+\vartheta_{l'}(x_n))^2\vartheta_{l'}(x_n)\Upsilon(\vartheta(x_n),k_{l,i})
+\end{equation}
+and
+\begin{equation}
+ \left<\mathds 1_{l',n}\mathfrak v\right>=
+ \frac{\tau_{l'+1}-\tau_{l'}}{32\pi}w_n\cos({\textstyle\frac{\pi x_n}2})(1+\vartheta_{l'}(x_n))^2\vartheta_{l'}(x_n)\Upsilon(\vartheta(x_n),0)
+ .
+\end{equation}
+\bigskip
+
+\point{\bf Evaluating $\hat l_3$.}
+The only term in\-~(\ref{anyeq}) that does not involve just convolutions (whose computation was described above) is $\hat l_3$ (\ref{l3}).
+To evaluate it, we first change variables, using a generalization of bipolar coordinates (see lemma\-~\ref{lemma:bipolar2}):
+\begin{equation}
+ \begin{largearray}
+ \hat l_3(|k|)
+ =
+ \frac1{(2\pi)^5\rho^2| k|^2}\int_0^\infty dt\int_{|| k|-t|}^{| k|+t}ds\int_0^\infty dt'\int_{|| k|-t'|}^{| k|+t'}ds'\int_0^{2\pi}d\theta\ sts't'U(s)U(t)U(s')U(t')
+ \cdot\\\hfill\cdot
+ S(\mathfrak R(s,t,s',t',\theta,| k|))
+ \end{largearray}
+\end{equation}
+with
+\begin{equation}
+ \begin{largearray}
+ \mathfrak R(s,t,s',t',\theta,| k|)
+ :=
+ \frac1{\sqrt 2| k|}
+ \Big(
+ | k|^2(s^2+t^2+(s')^2+(t')^2)-| k|^4-(s^2-t^2)((s')^2-(t')^2)
+ \\[0.5cm]\hfill
+ -
+ \sqrt{(4| k|^2s^2-(| k|^2+s^2-t^2)^2)(4| k|^2(s')^2-(| k|^2+(s')^2-(t')^2)^2)}\cos\theta
+ \Big)^{\frac12}
+ .
+ \end{largearray}
+\end{equation}
+We change variables as in\-~(\ref{convvar}):
+\begin{equation}
+ \begin{largearray}
+ \hat l_3(|k|)
+ =
+ \frac1{(2\pi)^5\rho^2| k|^2}
+ \int_{-1}^1 d\tau\ \frac{2(1-\tau)}{(1+\tau)^3}U({\textstyle\frac{1-\tau}{1+\tau}})
+ \int_{\alpha_-(| k|,\tau)}^{\alpha_+(| k|,\tau)} d\sigma\ \frac{2(1-\sigma)}{(1+\sigma)^3}U({\textstyle\frac{1-\sigma}{1+\sigma}})
+ \int_{-1}^1 d\tau'\ \frac{2(1-\tau')}{(1+\tau')^3}
+ \cdot\\[0.5cm]\hfill\cdot
+ U({\textstyle\frac{1-\tau'}{1+\tau'}})
+ \int_{\alpha_-(| k|,\tau')}^{\alpha_+(| k|,\tau')} d\sigma'\ \frac{2(1-\sigma')}{(1+\sigma')^3}U({\textstyle\frac{1-\sigma'}{1+\sigma'}})
+ \int_0^{2\pi}d\theta\ S(\mathfrak R({\textstyle \frac{1-\sigma}{1+\sigma},\frac{1-\tau}{1+\tau},\frac{1-\sigma'}{1+\sigma'},\frac{1-\tau'}{1+\tau'},\theta,| k|}))
+ .
+ \end{largearray}
+\end{equation}
+We expand $U$ and $ S$ into Chebyshev polynomials as in\-~(\ref{a_chebyshev_spline}), and split the integrals into splines:
+\begin{equation}
+ \hat l_3(|k_{l,j}|)
+ \approx
+ (\mathbb U^{\otimes4}\otimes\mathbb S)_{l,j}:=
+ \sum_{\lambda_1,\cdots,\lambda_5=0}^{J-1}
+ \sum_{n_1,\cdots,n_5=1}^\infty
+ \bar A_{\lambda_1,n_1;\cdots;\lambda_5,n_5}^{(\nu)}(|k_{l,j}|)
+ \prod_{i=1}^4
+ \left(\mathfrak F_{\lambda_i,n_i}^{(\nu)}(\mathbb U)\right)
+ \mathfrak F_{\lambda_5,n_5}^{(\nu)}(\mathbb S)
+ \label{otimes}
+\end{equation}
+with $\mathbb U_{l,j}:=U(k_{l,j})$, $\mathbb S_{l,j}:=S(k_{l,j})$ and
+\begin{equation}
+ \begin{largearray}
+ \bar A_{\lambda_1,n_1;\cdots;\lambda_5,n_5}^{(\nu)}(| k|)
+ =
+ \frac1{(2\pi)^5\rho^2| k|^2}
+ \int_{\tau_{\lambda_1}}^{\tau_{\lambda_1+1}} d\tau\ \frac{2(1-\tau)}{(1+\tau)^{3-\nu}}T_{n_1}({\textstyle\frac{2\tau-(\tau_{\lambda_1}+\tau_{\lambda_1+1})}{\tau_{\lambda_1+1}-\tau_{\lambda_1}}})
+ \cdot\\[0.5cm]\hskip1cm\cdot
+ \mathds 1_{\alpha_-(| k|,\tau)<\tau_{\lambda_2+1}}\mathds 1_{\alpha_+(| k|,\tau)>\tau_{\lambda_2}}
+ \int_{\max(\tau_{\lambda_2},\alpha_-(| k|,\tau))}^{\min(\tau_{\lambda_2+1},\alpha_+(| k|,\tau))} d\sigma\ \frac{2(1-\sigma)}{(1+\sigma)^{3-\nu}}T_{n_2}({\textstyle\frac{2\sigma-(\tau_{\lambda_2}+\tau_{\lambda_2+1})}{\tau_{\lambda_2+1}-\tau_{\lambda_2}}})
+ \cdot\\[0.5cm]\hskip1cm\cdot
+ \int_{\tau_{\lambda_3}}^{\tau_{\lambda_3+1}} d\tau'\ \frac{2(1-\tau')}{(1+\tau')^{3-\nu}}T_{n_3}({\textstyle\frac{2\tau'-(\tau_{\lambda_3}+\tau_{\lambda_3+1})}{\tau_{\lambda_3+1}-\tau_{\lambda_3}}})
+ \cdot\\[0.5cm]\hskip1cm\cdot
+ \mathds 1_{\alpha_-(| k|,\tau')<\tau_{\lambda_4+1}}\mathds 1_{\alpha_+(| k|,\tau')>\tau_{\lambda_4}}
+ \int_{\max(\tau_{\lambda_4},\alpha_-(| k|,\tau'))}^{\min(\tau_{\lambda_4+1},\alpha_+(| k|,\tau'))} d\sigma'\ \frac{2(1-\sigma')}{(1+\sigma')^{3-\nu}}T_{n_4}({\textstyle\frac{2\sigma'-(\tau_{\lambda_4}+\tau_{\lambda_4+1})}{\tau_{\lambda_4+1}-\tau_{\lambda_4}}})
+ \cdot\\[0.5cm]\hskip1cm\cdot
+ \int_0^{2\pi}d\theta\
+ \frac{2^\nu}{(2+\mathfrak R)^\nu}
+ T_{n_5}({\textstyle\frac{2\frac{1-\mathfrak R}{1+\mathfrak R}-(\tau_{\lambda_5}+\tau_{\lambda_5+1})}{\tau_{\lambda_5+1}-\tau_{\lambda_5}}})
+ \mathds 1_{\tau_{\lambda_5}<\frac{1-\mathfrak R}{1+\mathfrak R}<\tau_{\lambda_5+1}}
+ \end{largearray}
+\end{equation}
+in which $\mathfrak R$ is a shorthand for $\mathfrak R({\textstyle \frac{1-\sigma}{1+\sigma},\frac{1-\tau}{1+\tau},\frac{1-\sigma'}{1+\sigma'},\frac{1-\tau'}{1+\tau'},\theta,| k|})$.
+Note that $\bar A$ is independent of $U$, and can be computed once and for all at the beginning of execution.
+Since the tensor $\bar A$ is quite large (it contains $(NJ)^5$ entries), and its computation can be rather long it can be inconvenient to compute $\bar A$ at every execution.
+Instead, one can use the \refname{command:anyeq_save_Abar}{{\tt save\_Abar}} method to compute $\bar A$ and save it to a file, which can then be recalled via the {\tt -s} option on the command line.
+\bigskip
+
+\point{\bf Main algorithm to compute $U$.}
+We are now ready to detail how $U\equiv\rho\hat u$ is computed.
+All of the observables we are interested in are approximated from the values $\mathbb U_{l,j}:=U(k_{l,j})$ (\ref{klj}).
+\bigskip
+
+\subpoint
+The equation for $(\mathbb U_{l,j})_{l\in\{0,\cdots,J-1\},j\in\{1,\cdots,N\}}$ is obtained by approximating\-~(\ref{anyeq_hatu}) according to the prescriptions detailed above:
+\begin{equation}
+ \mathbb U_{l,j}:=
+ \frac{1+\mathbb Y_{l,j}}{2(\mathbb X_{l,j}+1)}\ \Phi\left({\textstyle\frac{1+\mathbb Y_{l,j}}{(\mathbb X_{l,j}+1)^2}}\right)
+ \label{bbU}
+\end{equation}
+\begin{equation}
+ \mathbb X_{l,j}:=\frac1{\mathbb L_{l,j}}\left(\mathbb K_{l,j}-\mathbb L_{l,j}+\frac{k_{l,j}^2}{2\rho}+\mathbb I_{l,j}\right)
+ ,\quad
+ \mathbb Y_{l,j}:=\frac1{\mathbb L_{l,j}}\left(\mathbb S_{l,j}-\mathbb L_{l,j}+\frac12\mathbb J_{l,j}+\mathbb G_{l,j}\right)
+\end{equation}
+\begin{equation}
+ \mathbb S_{l,j}:=
+ \mathfrak v_{l,j}-\frac1{\rho}(\mathbb U\odot\mathfrak v)_{l,j}
+ ,\quad
+ \mathfrak v_{l,j}:=\hat v(k_{l,j})
+ ,\quad
+ \mathbb E:=\hat v(0)-\frac1{\rho}\left<\mathbb U\mathfrak v\right>
+\end{equation}
+\begin{equation}
+ \mathbb I_{l,j}:=\frac1{\rho}\gamma_{L,2}(\beta_{L,2}(\mathbb U\odot(\mathbb U\mathbb S))_{l,j}+(1-\beta_{L,2})\mathbb E(\mathbb U\odot\mathbb U)_{l,j})
+\end{equation}
+\begin{equation}
+ \mathbb K_{l,j}:=\gamma_K(\beta_K\mathbb S_{l,j}+(1-\beta_K)\mathbb E)
+ ,\quad
+ \mathbb L_{l,j}:=\gamma_{L,1}(\beta_{L,1}\mathbb S_{l,j}+(1-\beta_{L,1})\mathbb E)
+\end{equation}
+\begin{equation}
+ \mathbb J_{l,j}:=\gamma_{L,3}(1-\beta_{L,3})\frac{\mathbb E}{\rho^2}(\mathbb U\odot\mathbb U)^2_{l,j}
+ +\gamma_{L,3}\beta_{L,3}(\mathbb U^{\otimes4}\otimes\mathbb S)_{l,j}
+\end{equation}
+\begin{equation}
+ \begin{largearray}
+ \mathbb G_{l,j}:=
+ \frac2{\rho}\gamma_K\alpha_K(\mathbb U\odot((\beta_K\mathbb S+(1-\beta_K)\mathbb E)\mathbb U))_{l,j}
+ \\[0.5cm]\hfill
+ -
+ \frac1{\rho}\alpha_{L,1}(\mathbb U\odot((\beta_{L,1}\mathbb S+(1-\beta_{L,1})\mathbb E)\mathbb U^2))_{l,j}
+ +
+ \frac2{\rho}\alpha_{L,2}(\mathbb U\odot(\mathbb I\mathbb U))_{l,j}
+ -
+ \frac1{2\rho}\alpha_{L,3}(\mathbb U\odot \mathbb J)_{l,j}
+ \end{largearray}
+\end{equation}
+(see\-~(\ref{odot}), (\ref{otimes}) and\-~(\ref{avg}) for the definitions of $\odot$, $\otimes$ and $\left<\cdot\right>$).
+\bigskip
+
+\subpoint
+We rewrite\-~(\ref{bbU}) as a root finding problem:
+\begin{equation}
+ \Xi_{l,j}(\mathbb U):=
+ \mathbb U_{l,j}-
+ \frac{1+\mathbb Y_{l,j}}{2(\mathbb X_{l,j}+1)}\ \Phi\left({\textstyle\frac{1+\mathbb Y_{l,j}}{(\mathbb X_{l,j}+1)^2}}\right)
+ =0
+ \label{root_anyeq}
+\end{equation}
+which we solve using the Newton algorithm, that is, we define a sequence of $\mathbb U$'s:
+\begin{equation}
+ \mathbb U^{(n+1)}=\mathbb U^{(n)}-(D\Xi(\mathbb U^{(n)}))^{-1}\Xi(\mathbb U^{(n)})
+\end{equation}
+where $D\Xi$ is the Jacobian of $\Xi$:
+\begin{equation}
+ (D\Xi)_{l,j;l',i}:=\frac{\partial\Xi_{l,j}}{\partial\mathbb U_{l',i}}
+ .
+\end{equation}
+\bigskip
+
+\subpoint
+We initialize the algorithm with the solution of the \refname{eq:easyeq_medeq}{Medium equation}, which is computed using the \refname{sec:easyeq}{{\tt easyeq}} method.
+However, \refname{sec:easyeq}{{\tt easyeq}} only computes $\hat u$ at the momenta given by the Gauss-Legendre quadratures\-~(\ref{easyeq_ki}).
+To obtain a value for $\hat u$ at $k_{l,j}$, we use a linear interpolation (code is provided for a polynomial interpolation, which has not performed as well).
+The parameters \refname{param:anyeq_tolerance}{{\tt tolerance}}, \refname{param:anyeq_maxiter}{{\tt maxiter}}, \refname{param:anyeq_minlrho_init}{{\tt minlrho\_init}}, \refname{param:anyeq_nlrho_init}{{\tt nlrho\_init}} are passed on to \refname{sec:easyeq}{easyeq} as is, and the order of the Gauss-Legendre quadratures is set to \refname{param:anyeq_J}{{\tt J}}$\times$\refname{param:anyeq_N}{{\tt N}}.
+\bigskip
+
+\subpoint
+We are left with computing the Jacobian of $\Xi$:
+\begin{equation}
+ \begin{largearray}
+ \partial_{l',i}\Xi_{l,j}\equiv
+ \frac{\partial\Xi_{l,j}}{\partial\mathbb U_{l',i}}=
+ \delta_{l,l'}\delta_{i,j}
+ +\frac1{2(\mathbb X_{l,j}+1)}\left(
+ \frac{(1+\mathbb Y_{l,j})\partial_{l',i}\mathbb X_{l,j}}{\mathbb X_{l,j}+1}
+ -
+ \partial_{l',i}\mathbb Y_{l,j}
+ \right)
+ \Phi\left({\textstyle\frac{1+\mathbb Y_{l,j}}{(\mathbb X_{l,j}+1)^2}}\right)
+ \\[0.5cm]\hfill
+ +\frac{(1+\mathbb Y_{l,j})}{2(\mathbb X_{l,j}+1)^3}\left(
+ \frac{2(1+\mathbb Y_{l,j})}{\mathbb X_{l,j}+1}\partial_{l',i}\mathbb X_{l,j}
+ -\partial_{l',i}\mathbb Y_{l,j}
+ \right)\ \partial\Phi\left({\textstyle\frac{1+\mathbb Y_{l,j}}{(\mathbb X_{l,j}+1)^2}}\right)
+ \end{largearray}
+\end{equation}
+with
+\begin{equation}
+ \partial_{l',i}\mathbb X_{l,j}=
+ \frac1{\mathbb L_{l,j}}\left(\partial_{l',i}\mathbb K_{l,j}-\partial_{l',i}\mathbb L_{l,j}+\partial_{l',i}\mathbb I_{l,j}\right)
+ -
+ \frac{\partial_{l',i}\mathbb L_{l,j}}{\mathbb L_{l,j}}\mathbb X_{l,j}
+\end{equation}
+\begin{equation}
+ \partial_{l',i}\mathbb Y_{l,j}=
+ \frac1{\mathbb L_{l,j}}\left(\partial_{l',i}\mathbb S_{l,j}-\partial_{l',i}\mathbb L_{l,j}+\frac12\partial_{l',i}\mathbb J_{l,j}+\partial_{l',i}\mathbb G_{l,j}\right)
+ -
+ \frac{\partial_{l',i}\mathbb L_{l,j}}{\mathbb L_{l,j}}\mathbb Y_{l,j}
+\end{equation}
+\begin{equation}
+ \partial_{l',i}\mathbb S_{l,j}=
+ -\frac1{\rho}(\mathds 1_{l',i}\odot\mathfrak v)_{l,j}
+ ,\quad
+ \partial_{l',i}\mathbb E=-\frac1{\rho}\left<\mathds 1_{l',i}\mathfrak v\right>
+\end{equation}
+\begin{equation}
+ \partial_{l',i}\mathbb K_{l,j}:=\gamma_K(\beta_K\partial_{l',i}\mathbb S_{l,j}+(1-\beta_K)\partial_{l',i}\mathbb E)
+ ,\quad
+ \partial_{l',i}\mathbb L_{l,j}:=\gamma_{L,1}(\beta_{L,1}\partial_{l',i}\mathbb S_{l,j}+(1-\beta_{L,1})\partial_{l',i}\mathbb E)
+\end{equation}
+\begin{equation}
+ \begin{largearray}
+ \partial_{l',i}\mathbb I_{l,j}=
+ \frac1{\rho}\gamma_{L,2}\left(\beta_{L,2}(
+ \mathds 1_{l',i}\odot(\mathbb U\mathbb S)
+ +
+ \mathbb U\odot(\mathds 1_{l',i}\mathbb S+\mathbb U\partial_{l',i}\mathbb S)
+ )_{l,j}
+ \right.\\[0.5cm]\hfill\left.
+ +
+ (1-\beta_{L,2})(
+ \partial_{l',i}\mathbb E(\mathbb U\odot\mathbb U)_{l,j}
+ +
+ 2\mathbb E(\mathbb U\odot\mathds 1_{l',i})_{l,j}
+ )\right)
+ \end{largearray}
+\end{equation}
+\begin{equation}
+ \begin{largearray}
+ \partial_{l',i}\mathbb J_{l,j}=
+ \frac1{\rho^2}\gamma_{L,3}(1-\beta_{L,3})\left(
+ \partial_{l',i}\mathbb E(\mathbb U\odot\mathbb U)^2_{l,j}
+ +
+ 4\mathbb E(\mathbb U\odot\mathbb U)_{l,j}(\mathbb U\odot\mathds 1_{l',i})_{l,j}
+ \right)
+ \\[0.5cm]\hfill
+ +\gamma_{L,3}\beta_{L,3}(
+ 4\mathds 1_{l',i}\otimes\mathbb U^{\otimes3}\otimes\mathbb S
+ +
+ \mathbb U^{\otimes4}\otimes\partial_{l',i}\mathbb S
+ )_{l,j}
+ \end{largearray}
+\end{equation}
+\begin{equation}
+ \begin{largearray}
+ \partial_{l',i}\mathbb G_{l,j}=
+ \frac2{\rho}\gamma_K\alpha_K\beta_K\left(
+ \mathds 1_{l',i}\odot(\mathbb S\mathbb U)
+ +
+ \mathbb U\odot(\mathbb S\mathds 1_{l',i}
+ +\partial_{l',i}\mathbb S\mathbb U)
+ \right)_{l,j}
+ \\[0.5cm]\hfill
+ +\frac2{\rho}\gamma_K\alpha_K(1-\beta_K)\left(
+ \partial_{l',i}\mathbb E(\mathbb U\odot\mathbb U)_{l,j}
+ +2\mathbb E(\mathds 1_{l',i}\odot\mathbb U)_{l,j}
+ \right)
+ \\[0.5cm]\indent
+ -
+ \frac1{\rho}\alpha_{L,1}\beta_{L,1}\left(
+ \mathds 1_{l',i}\odot(\mathbb S\mathbb U^2)
+ +
+ \mathbb U\odot(
+ \partial_{l',i}\mathbb S\mathbb U^2
+ +
+ 2\mathbb S\mathbb U\mathds 1_{l',i}
+ )
+ \right)_{l,j}
+ \\[0.5cm]\hfill
+ -
+ \frac1{\rho}\alpha_{L,1}(1-\beta_{L,1})\left(
+ \mathbb E\mathds 1_{l',i}\odot\mathbb U^2
+ +
+ \mathbb U\odot(
+ \partial_{l',i}\mathbb E\mathbb U^2
+ +
+ 2\mathbb E\mathbb U\mathds 1_{l',i}
+ )
+ \right)_{l,j}
+ \\[0.5cm]\hfill
+ +
+ \frac2{\rho}\alpha_{L,2}(
+ (\mathds 1_{l',i}\odot(\mathbb I\mathbb U))_{l,j}
+ +
+ \mathbb U\odot(
+ \partial_{l',i}\mathbb I\mathbb U
+ +
+ \mathbb I\mathds 1_{l',i})
+ )_{l,j}
+ -
+ \frac1{2\rho}\alpha_{L,3}(
+ \mathds 1_{l',i}\odot \mathbb J
+ +
+ \mathbb U\odot\partial_{l',i}\mathbb J
+ )_{l,j}
+ .
+ \end{largearray}
+\end{equation}
+\bigskip
+
+\subpoint
+We iterate the Newton algorithm until the Newton relative error $\epsilon$ becomes smaller than the \refname{param:easyeq_tolerance}{{\tt tolerance}} parameter.
+The Newton error is defined as
+\begin{equation}
+ \epsilon=\frac{\|\mathbb U^{(n+1)}-\mathbb U^{(n)}\|_2}{\|\mathbb U^{(n)}\|_2}
+\end{equation}
+where $\|\cdot\|_2$ is the $l_2$ norm.
+The energy thus obtained is
+\begin{equation}
+ e=\frac\rho2\mathds E
+\end{equation}
+the Fourier transform $\hat u$ of the solution is
+\begin{equation}
+ \hat u(k_{l,j})\approx\frac{\mathbb U_{l,j}}\rho
+\end{equation}
+where $k_{l,j}$ was defined in\-~(\ref{klj}), and the solution $u$ in real space is obtained by inverting the Fourier transform, following the prescription of\-~(\ref{anyeq_integration}):
+\begin{equation}
+ u(|x|)=\int \frac{dk}{(2\pi)^3}\ e^{-ikx}\hat u(|k|)
+ \approx
+ \sum_{l=0}^{J-1}
+ \frac{\tau_{l+1}-\tau_l}{16\pi}
+ \sum_{j=1}^Nw_j
+ \cos({\textstyle\frac{\pi x_j}2})(1+\vartheta_l(x_j))^2\vartheta_l(x_j)\mathbb U_{l,j}\sin(\vartheta_l(x_j)|x|)
+ .
+\end{equation}
+\bigskip
+
+\point{\bf Condensate fraction.}
+To compute the condensate fraction, we solve the modified {\tt anyeq} (see\-~\cite{CJL20b}):
+\begin{equation}
+ (-\Delta+2\mu)u_\mu
+ =
+ (1-u_\mu)v-2\rho K+\rho^2 L
+ .
+\end{equation}
+where $K$ and $L$ are defined as in\-~(\ref{anyeq_K})-(\ref{anyeq_e}) in which $u$ is replaced with $u_\mu$.
+The uncondensed fraction is then
+\begin{equation}
+ \eta=\partial_\mu e|_{\mu=0}
+ =-\frac\rho2\int dx\ v(x)\partial_\mu u_\mu(x)|_{\mu=0}
+ .
+\end{equation}
+To compute the energy in the presence of the parameter $\mu$, we proceed in the same way as for $\mu=0$, the only difference being that $k^2$ should formally be replaced by $k^2+2\mu$.
+In other words, we consider $\mathbb U_{j,l}=u_\mu(|k_{j,l}|)$ and define $\Xi(\mathbb U,\mu)$ in the same way as in\-~(\ref{root_anyeq}), except that $\mathbb X_i$ should be replaced by
+\begin{equation}
+ \mathbb X_{l,j}=\frac1{\mathbb L_{l,j}}\left(\mathbb K_{l,j}-\mathbb L_{l,j}+\frac{k_{l,j}^2+2\mu}{2\rho}+\mathbb I_{l,j}\right)
+ .
+\end{equation}
+We then solve
+\begin{equation}
+ \Xi(\mathbb U_\mu,\mu)=0
+\end{equation}
+By differentiating this identity with respect to $\mu$, we find $\partial_\mu u_\mu$:
+\begin{equation}
+ \partial_\mu \mathbb U|_{\mu=0}=-(D\Xi)^{-1}\partial_\mu\Xi|_{\mu=0}
+\end{equation}
+and
+\begin{equation}
+ \partial_\mu\Xi|_{\mu=0}=
+ \frac{(1+\mathbb Y_{l,j})\partial_\mu\mathbb X_{l,j}}{2(\mathbb X_{l,j}+1)^2}
+ \Phi\left({\textstyle\frac{1+\mathbb Y_{l,j}}{(\mathbb X_{l,j}+1)^2}}\right)
+ +\frac{(1+\mathbb Y_{l,j})^2}{(\mathbb X_{l,j}+1)^4}\partial_\mu\mathbb X_{l,j}
+ \partial\Phi\left({\textstyle\frac{1+\mathbb Y_{l,j}}{(\mathbb X_{l,j}+1)^2}}\right)
+ ,\quad
+ \partial_\mu\mathbb X_{l,j}=\frac1{\rho\mathbb L_{l,j}}
+ .
+\end{equation}
+We then approximate
+\begin{equation}
+ \eta\approx
+ -\frac12\left<\mathfrak v\partial_\mu\mathbb U\right>
+\end{equation}
+(see\-~(\ref{avg})).
+\bigskip
+
+\point{\bf Correlation function.}
+The two-point correlation function is
+\begin{equation}
+ C_2(x):=
+ 2\rho\frac{\delta e}{\delta v(x)}
+ .
+\end{equation}
+In Fourier space,
+\begin{equation}
+ C_2(x)=
+ 2\rho\int dk\ e^{ikx}\frac{\delta e}{\delta\hat v(k)}
+ =2\rho\int dk\ \frac{\sin(|k||x|)}{|k||x|}\frac{\delta e}{\delta\hat v(k)}
+ .
+ \label{C2fourier}
+\end{equation}
+\bigskip
+
+\subpoint
+We can compute this quantity by considering a modified {\tt anyeq} in Fourier space, by formally replacing $\hat v$ with
+\begin{equation}
+ \hat v+\lambda g(|k|)
+ ,\quad
+ g(|k|):=\frac{\sin(|k||x|)}{|k||x|}
+ .
+\end{equation}
+Indeed, if $e_\lambda$ denotes the energy of this modified equation,
+\begin{equation}
+ \partial_\lambda e_\lambda|_{\lambda=0}
+ =\int dk\ \frac{\delta e}{\hat v(k)}\partial_\lambda({\textstyle \hat v(k)+\lambda g(|k|)})
+ =\int dk\ g(|k|)\frac{\delta e}{\hat v(k)}
+\end{equation}
+so, denoting the solution of the modified equation by $u_\lambda$,
+\begin{equation}
+ C_2(x)=2\rho\partial_\lambda e_\lambda|_{\lambda=0}
+ =-\rho^2\int dx\ (g(x)u_0(x)+v(x)\partial_\lambda u_\lambda(x)|_{\lambda=0})
+ .
+\end{equation}
+We compute $\partial_\lambda u_\lambda|_{\lambda=0}$ in the same way as the uncondensed fraction: we define $\Xi(\mathbb U,\lambda)$ by formally adding $\lambda g(|k|)$ to $\hat v$, solve $\Xi(\mathbb U,\lambda)=0$, and differentiate:
+\begin{equation}
+ \partial_\lambda\mathbb U|_{\lambda=0}=-(D\Xi)^{-1}\partial_\lambda\Xi|_{\lambda=0}
+ .
+\end{equation}
+\bigskip
+
+\subpoint
+We compute $\partial_\lambda\Xi|_{\lambda=0}$:
+\begin{equation}
+ \begin{largearray}
+ \partial_\lambda\Xi_{l,j}=
+ \delta_{l,l'}\delta_{i,j}
+ +\frac1{2(\mathbb X_{l,j}+1)}\left(
+ \frac{(1+\mathbb Y_{l,j})\partial_\lambda\mathbb X_{l,j}}{\mathbb X_{l,j}+1}
+ -
+ \partial_\lambda\mathbb Y_{l,j}
+ \right)
+ \Phi\left({\textstyle\frac{1+\mathbb Y_{l,j}}{(\mathbb X_{l,j}+1)^2}}\right)
+ \\[0.5cm]\hfill
+ +\frac{(1+\mathbb Y_{l,j})}{2(\mathbb X_{l,j}+1)^3}\left(
+ \frac{2(1+\mathbb Y_{l,j})}{\mathbb X_{l,j}+1}\partial_\lambda\mathbb X_{l,j}
+ -\partial_\lambda\mathbb Y_{l,j}
+ \right)\ \partial\Phi\left({\textstyle\frac{1+\mathbb Y_{l,j}}{(\mathbb X_{l,j}+1)^2}}\right)
+ \end{largearray}
+\end{equation}
+with
+\begin{equation}
+ \partial_\lambda\mathbb S_{l,j}=
+ \mathfrak g_{l,j}
+ -\frac1{\rho}(\mathbb U\odot\mathfrak g)_{l,j}
+ ,\quad
+ \partial_\lambda\mathbb E=g(0)-\frac1{\rho}\left<\mathbb U\mathfrak g\right>
+\end{equation}
+\begin{equation}
+ \partial_\lambda\mathbb X_{l,j}=
+ \frac1{\mathbb L_{l,j}}\left(\partial_\lambda\mathbb K_{l,j}-\partial_\lambda\mathbb L_{l,j}+\partial_\lambda\mathbb I_{l,j}\right)
+ -
+ \frac{\partial_\lambda\mathbb L_{l,j}}{\mathbb L_{l,j}}\mathbb X_{l,j}
+\end{equation}
+\begin{equation}
+ \partial_\lambda\mathbb Y_{l,j}=
+ \frac1{\mathbb L_{l,j}}\left(\partial_\lambda\mathbb S_{l,j}-\partial_\lambda\mathbb L_{l,j}+\frac12\partial_\lambda\mathbb J_{l,j}+\partial_\lambda\mathbb G_{l,j}\right)
+ -
+ \frac{\partial_\lambda\mathbb L_{l,j}}{\mathbb L_{l,j}}\mathbb Y_{l,j}
+\end{equation}
+\begin{equation}
+ \partial_\lambda\mathbb K_{l,j}:=\gamma_K(\beta_K\partial_\lambda\mathbb S_{l,j}+(1-\beta_K)\partial_\lambda\mathbb E)
+ ,\quad
+ \partial_\lambda\mathbb L_{l,j}:=\gamma_{L,1}(\beta_{L,1}\partial_\lambda\mathbb S_{l,j}+(1-\beta_{L,1})\partial_\lambda\mathbb E)
+\end{equation}
+\begin{equation}
+ \partial_\lambda\mathbb I_{l,j}=
+ \frac1{\rho}\gamma_{L,2}\left(
+ \beta_{L,2}(\mathbb U\odot(\mathbb U\partial_\lambda\mathbb S)_{l,j}
+ +
+ (1-\beta_{L,2})\partial_\lambda\mathbb E(\mathbb U\odot\mathbb U)_{l,j}
+ \right)
+\end{equation}
+\begin{equation}
+ \partial_\lambda\mathbb J_{l,j}=
+ \frac1{\rho^2}\gamma_{L,3}(1-\beta_{L,3})\partial_\lambda\mathbb E(\mathbb U\odot\mathbb U)^2_{l,j}
+ +\gamma_{L,3}\beta_{L,3}(\mathbb U^{\otimes4}\otimes\partial_\lambda\mathbb S)_{l,j}
+\end{equation}
+\begin{equation}
+ \begin{largearray}
+ \partial_\lambda\mathbb G_{l,j}=
+ \frac2{\rho}\gamma_K\alpha_K\beta_K\left(\partial_\lambda\mathbb S\mathbb U\right)_{l,j}
+ +\frac2{\rho}\gamma_K\alpha_K(1-\beta_K)\partial_\lambda\mathbb E(\mathbb U\odot\mathbb U)_{l,j}
+ -
+ \frac1{\rho}\alpha_{L,1}\beta_{L,1}\left(\mathbb U\odot\partial_\lambda\mathbb S\mathbb U^2\right)_{l,j}
+ \\[0.5cm]\hfill
+ -
+ \frac1{\rho}\alpha_{L,1}(1-\beta_{L,1})\partial_\lambda\mathbb E\left(\mathbb U\odot(\mathbb U^2)\right)_{l,j}
+ +
+ \frac2{\rho}\alpha_{L,2}\mathbb U\odot(\partial_\lambda\mathbb I\mathbb U)_{l,j}
+ -
+ \frac1{2\rho}\alpha_{L,3}(\mathbb U\odot\partial_\lambda\mathbb J)_{l,j}
+ .
+ \end{largearray}
+\end{equation}
+To evaluate $(\mathbb U\odot\mathfrak g)$ and $\left<\mathbb U\mathfrak g\right>$, we proceed as in\-~(\ref{adotv}) and\-~(\ref{<av>}).
+To do so, we replace $\hat v$ with $g$ in the computation of $\Upsilon$.
+\bigskip
+
+\subpoint
+In order to invert the Fourier transform in\-~(\ref{C2fourier}) numerically, we will use a Hann window (see appendix\-~\ref{appendix:hann})
+\begin{equation}
+ H_L(k):=\mathds 1_{|k|<\frac L2}\cos^2({\textstyle\frac{\pi|k|}{L}})
+ .
+ \label{hann}
+\end{equation}
+The parameter $L$ is set using \refname{param:anyeq_window_L}{{\tt window\_L}}.
+The computation is changed only in that $g$ is changed to $H_L(k)\frac{\sin(|k||x|)}{|k||x|}$.
+\bigskip
+
+\point {\bf Momentum distribution.}
+To compute the momentum distribution (see\-~\cite{CHe21}), we add a parameter $\lambda$ to {\tt anyeq}:
+\begin{equation}
+ -\Delta u_\lambda(|x|)
+ =
+ (1-u_\lambda(|x|))v(|x|)-2\rho K(|x|)+\rho^2 L(|x|)
+ -2\lambda \hat u_0(q)\cos(q\cdot x)
+\end{equation}
+($\hat u_0\equiv\hat u_\lambda|_{\lambda=0}$).
+The momentum distribution is then
+\begin{equation}
+ \mathcal M(q)=\partial_\lambda e|_{\lambda=0}
+ =-\frac\rho2\int dx\ v(x)\partial_\lambda u_\lambda(x)|_{\lambda=0}
+ .
+\end{equation}
+Note that the Fourier transform of $2\lambda\hat u_0(q)\cos(q\cdot x)$ is
+\begin{equation}
+ -(2\pi)^3\lambda\hat u_0(q)(\delta(q+k)+\delta(q-k))
+ .
+ \label{fouriermomentum}
+\end{equation}
+We compute $\partial_\lambda u_\lambda|_{\lambda=0}$ in the same way as the uncondensed fraction.
+\bigskip
+
+\subpoint
+In order to do so we will discretize momentum space, see\-~(\ref{klj}), and so it is necessary to construct a discrete analog of the delta-functions in\-~(\ref{fouriermomentum}).
+The starting point we take is
+\begin{equation}
+ \int dk f(k)\delta(k-q)
+ =f(q)
+\end{equation}
+so, when approximating the integral according to\-~(\ref{anyeq_integration}), we find
+\begin{equation}
+ \frac{\pi^2}2\sum_{l=0}^{J-1}
+ (\tau_{l+1}-\tau_l)
+ \sum_{j=1}^Nw_j
+ \cos({\textstyle\frac{\pi x_j}2})(1+\vartheta_l(x_j))^2\vartheta_l^2(x_j)f(\vartheta_l(x_j))\tilde\delta(\vartheta_l(x_j)-k_{l',i})
+ \approx
+ f(k_{l',i})
+\end{equation}
+where $\tilde\delta$ is the approximation of the delta-function.
+Since
+\begin{equation}
+ \vartheta_l(x_j)\equiv k_{l,j}
+\end{equation}
+(see\-~(\ref{chebyshevvars})), we find that the definition of $\tilde\delta$ must be
+\begin{equation}
+ \tilde\delta_{l,j;l',i}
+ :=
+ \delta_{l,l'}\delta_{j,i}
+ \frac2{\pi^2}
+ \left(
+ (\tau_{l+1}-\tau_l)
+ w_j
+ \cos({\textstyle\frac{\pi x_j}2})
+ (1+k_{l,j})^2k_{l,j}^2
+ \right)^{-1}
+ .
+\end{equation}
+Note that, due to the invariance under rotation, the approximation for $\delta(q+k)$ is equal to that for $\delta(q-k)$.
+\bigskip
+
+\subpoint
+To compute the momentum distribution at $q=k_{l',i}$, we define $\Xi(\mathbb U,\lambda)$ by formally adding $-2(2\pi)^3\lambda \hat u_0(k_{l',i})\tilde\delta_{l,j;l',i}$ to $\mathbb G_{l,j}$, which corresponds to replacing $\mathbb Y$ with
+\begin{equation}
+ \mathbb Y_{l,j}=
+ \frac1{\mathbb L_{l,j}}\left(\mathbb S_{l,j}-\mathbb L_{l,j}+\frac12\mathbb J_{l,j}+\mathbb G_{l,j}-2(2\pi)^3\lambda\frac{\mathbb U_{l',i}}\rho\tilde\delta_{l,j;l',i}\right)
+\end{equation}
+Then we solve $\Xi(\mathbb U,\lambda)=0$, and differentiate:
+\begin{equation}
+ \partial_\lambda\mathbb U|_{\lambda=0}=-(D\Xi)^{-1}\partial_\lambda\Xi|_{\lambda=0}
+ .
+\end{equation}
+Finally,
+\begin{equation}
+ \partial_\lambda\Xi_{l,j}|_{\lambda=0}
+ =
+ -\partial_\lambda\mathbb Y_{l,j}|_{\lambda=0}\left(
+ \frac1{2(\mathbb X_{l,j}+1)}
+ \Phi\left({\textstyle\frac{1+\mathbb Y_{l,j}}{(\mathbb X_{l,j}+1)^2}}\right)
+ +\frac{(1+\mathbb Y_{l,j})}{2(\mathbb X_{l,j}+1)^3}
+ \partial\Phi\left({\textstyle\frac{1+\mathbb Y_{l,j}}{(\mathbb X_{l,j}+1)^2}}\right)
+ \right)
+\end{equation}
+with
+\begin{equation}
+ \partial_\lambda\mathbb Y_{l,j}|_{\lambda=0}=
+ \frac{2(2\pi)^3\mathbb U_{l',i}\tilde\delta_{l,j;l',i}}{\rho\mathbb L_{l,j}}
+ .
+\end{equation}
+
+\subsection{{\tt simpleq-Kv}}\label{sec:simpleq-Kv}
+\indent
+The method is used to compute observables for the simple equation
+\begin{equation}
+ -\Delta u
+ =
+ v(1-u)-4eu+2e\rho u\ast u
+ ,\quad
+ e=\frac\rho2\int dx\ (1-u(|x|))v(|x|)
+ .
+ \label{simpleq}
+\end{equation}
+One can show\-~\cite[Theorem\-~1.6]{CJL20b} that the condensate fraction is
+\begin{equation}
+ \eta=\frac{\rho\int v(x)\mathfrak Ku(x)\ dx}{1-\rho\int v(x)\mathfrak K(2u(x)-\rho u\ast u(x))\ dx}
+ \label{simpleq-Kv_eta}
+\end{equation}
+with
+\begin{equation}\label{bg6}
+ \mathfrak K = (-\Delta + v + 4e(1 - \rho u\ast))^{-1}
+ .
+ \label{Kv}
+\end{equation}
+Similarly, the two-point correlation function is\-~\cite[(45)]{CHe21}
+\begin{equation}
+ C_2=
+ \rho^2(1-u)+
+ \rho^2\frac{\mathfrak Kv(1-u)-2\rho u\ast \mathfrak Kv+\rho^2u\ast u\ast \mathfrak Kv}{1-\rho\int dx\ v(x)\mathfrak K(2u(x)-\rho u\ast u(x))}
+ .
+ \label{simpleq-Kv_C2}
+\end{equation}
+Thus, using the fact that $\mathfrak K$ is self-adjoint, we can compute these observables of the simple equation directly from the knowledge of $\mathfrak Kv$.
+\bigskip
+
+\subsubsection{Usage}
+\indent
+The computation uses the same approximation scheme as \refname{sec:anyeq}{{\tt anyeq}}, as well as using the solution of \refname{sec:anyeq}{{\tt anyeq}}.
+As such, it takes a similar list of parameters:
+\refname{param:anyeq_rho}{{\tt rho}},
+\refname{param:anyeq_tolerance}{{\tt tolerance}},
+\refname{param:anyeq_maxiter}{{\tt maxiter}},
+\refname{param:anyeq_P}{{\tt P}},
+\refname{param:anyeq_N}{{\tt N}},
+\refname{param:anyeq_J}{{\tt J}},
+\refname{param:anyeq_minlrho_init}{{\tt minlrho\_init}},
+\refname{param:anyeq_nlrho_init}{{\tt nlrho\_init}}.
+\bigskip
+
+The available {\tt commands} are the following.
+\bigskip
+
+\begin{itemize}
+ \item\makelink{command:simpleq-Kv_Kv}{}
+ {\tt Kv}: compute $\mathfrak Kv$ as a function of $|x|$.\par
+ \underline{Extra parameters}:
+ \begin{itemize}
+ \item\makelink{param:simpleq-Kv_xmin}{}
+ {\tt xmin} ({\tt Float64}, default: 0): minimum of the range of $|x|$ to be printed.
+
+ \item\makelink{param:simpleq-Kv_xmax}{}
+ {\tt xmax} ({\tt Float64}, default: 100): maximum of the range of $|x|$ to be printed.
+
+ \item\makelink{param:simpleq-Kv_nx}{}
+ {\tt nx} ({\tt Int64}, default: 100): number of points to print (linearly spaced).
+
+ \end{itemize}
+ \underline{Output} (one line for each value of $|x|$): [$|x|$] [$\mathfrak K v$]
+
+ \item\makelink{command:simpleq-Kv_condensate-fraction}{}
+ {\tt condensate-fraction}: compute the uncondensed fraction as a function of $\rho$\par
+ \underline{Extra parameters}:
+ \begin{itemize}
+ \item\makelink{param:simpleq-Kv_minlrho}{}
+ {\tt minlrho} ({\tt Float64}, default: $10^{-6}$): minimal value for $\log_{10}\rho$.
+
+ \item\makelink{param:simpleq-Kv_maxlrho}{}
+ {\tt maxlrho} ({\tt Float64}, default: $10^{2}$): maximal value for $\log_{10}\rho$.
+
+ \item\makelink{param:simpleq-Kv_nlrho}{}
+ {\tt nlrho} ({\tt Int64}, default: $100$): number of values for $\rho$ (spaced logarithmically).
+
+ \item\makelink{param:simpleq-Kv_rhos}{}
+ {\tt rhos} ({\tt Array\{Float64\}}, default: $(10^{{\tt minlrho}+\frac{{\tt maxlrho}-{\tt minlrho}}{{\tt nlrho}}n})_n$: list of values for $\rho$, specified as a `{\tt,}' separated list.
+ \end{itemize}
+ \underline{Output} (one line for each value of $\rho$): [$\rho$] [$\eta$]
+
+ \item\makelink{command:simpleq-Kv_2pt}{}
+ {\tt 2pt}: compute the two-point correlation as a function of $|x|$.\par
+ \underline{Extra parameters}: same as \refname{command:simpleq-Kv_Kv}{{\tt Kv}}.\par
+ \underline{Output} (one line for each value of $|x|$): [$|x|$] [$C_2$]
+\end{itemize}
+
+\subsubsection{Description}
+\indent
+In Fourier space\-~(\ref{anyeq_fourier}),
+\begin{equation}
+ \hat{\mathfrak K}^{-1}f
+ :=
+ \int dx\ e^{ikx}
+ (-\Delta+4e(1-\rho u\ast)+v)f
+ =(k^2+4e(1-\rho\hat u(|k|))+\hat v\hat\ast)\hat f
+\end{equation}
+where $\hat\ast$ is defined in\-~(\ref{anyeq_hatast}).
+We follow the same approximation scheme as \refname{sec:anyeq}{{\tt anyeq}}:
+\begin{equation}
+ \hat{\mathfrak K}^{-1}f(k_{l,j})
+ \approx(k_{l,j}^2+4e(1-\mathbb U_{l,j}))\mathfrak f_{l,j}
+ +
+ (\mathfrak v\odot\mathfrak f)_{l,j}
+\end{equation}
+with $\mathfrak f_{l,j}:=f(k_{l,j})$, $\mathbb U_{l,j}:=\rho u(|k_{l,j}|)$, $\odot$ is defined in\-~(\ref{odot}), and $k_{l,j}$ is defined in\-~(\ref{klj}).
+Therefore, we approximate the operator $\hat{\mathfrak K}^{-1}$ by a matrix:
+\begin{equation}
+ \hat{\mathfrak K}^{-1}f(k_{l,j})\approx
+ \sum_{l'=0}^{J-1}\sum_{i=1}^N M_{l,j;l',i}\mathfrak f_{l',i}
+\end{equation}
+with, by\-~(\ref{odot}) and\-~(\ref{frakF}),
+\begin{equation}
+ \begin{largearray}
+ M_{l,j;l',i}:=
+ \delta_{l',l}\delta_{j,i}(k_{l,j}^2+4e(1-\mathbb U_{l,j}))
+ \\\hfill
+ +
+ \frac1{4\pi^2|k_{l,j}|}\sum_{n,m=0}^P\sum_{l''=0}^{J-1}\mathfrak F_{l'',n}^{(\nu_v)}(\mathfrak v)
+ A_{l'',n;l',m}^{(\nu_v,\nu_f)}(|k_{l,j}|)
+ \frac{\frac{2-\delta_{m,0}}2w_i\cos(\frac{m\pi(1+x_i)}2)}{(1-\frac{\tau_{l'+1}-\tau_{l'}}2\sin(\frac{\pi x_i}2)+\frac{\tau_{l'+1}+\tau_{l'}}2)^{\nu_f}}
+ .
+ \end{largearray}
+\end{equation}
+Defining $\mathds 1_{l',i}$ as the vector whose only non-vanishing component is that indexed by $l',i$ which is equal to 1, we can rewrite
+\begin{equation}
+ M_{l,j;l',i}:=
+ \delta_{l',l}\delta_{j,i}(k_{l,j}^2+4e(1-\mathbb U_{l,j}))
+ +
+ (\mathfrak v\odot\mathds 1_{l',i})_{l,j}
+ .
+\end{equation}
+Thus
+\begin{equation}
+ \mathfrak Kv\approx M^{-1}\mathfrak v
+ .
+\end{equation}
+\bigskip
+
+\indent
+To compute\-~(\ref{simpleq-Kv_eta}), we write
+\begin{equation}
+ \eta=\frac{\rho\int\frac{dk}{(2\pi)^3} \hat u(k)\hat{\mathfrak K}\hat v(k)}{1-\rho\int \frac{dk}{(2\pi)^3)}(2\hat u(k)-\rho\hat u^2(k))\hat{\mathfrak K}\hat v(k)}
+\end{equation}
+which we approximate as
+\begin{equation}
+ \eta\approx\frac{\left<\mathbb UM^{-1}\mathfrak v\right>}{1-\left<(2\mathbb U-\mathbb U^2)M^{-1}\mathfrak v\right>}
+\end{equation}
+where $\left<\cdot\right>$ is defined in\-~(\ref{avg}).
+We can thus compute $\eta$ using the solution $\mathbb U$ computed by \refname{sec:anyeq}{{\tt anyeq}}.
+\bigskip
+
+\indent
+To compute\-~(\ref{simpleq-Kv_C2}), we write
+\begin{equation}
+ C_2=
+ \rho^2(1-u(x))+
+ \rho^2\frac{\mathfrak Kv(x)(1-u(x))+\int\frac{dk}{(2\pi)^3}(-2\rho\hat u\hat{\mathfrak K}\hat v+\rho^2\hat u^2\hat{\mathfrak K}\hat v)}{1-\rho\int\frac{dk}{(2\pi)^3}\ (2\hat u(k)-\rho \hat u^2(k))\hat{\mathfrak K}\hat v(k)}
+\end{equation}
+which we approximate as
+\begin{equation}
+ C_2\approx
+ \rho^2-\rho\left<e^{-ik_{l,j}x}\mathbb U\right>+
+ \rho^2\frac{\left<M^{-1}\mathfrak v\right>(1-\rho^{-1}\left<e^{-ik_{l,j}x}\mathbb U\right>)+\left<(-2\mathbb U M^{-1}\mathfrak v+\mathbb UM^{-1}\mathfrak v)\right>}{1-\left<(2\mathbb U-\mathbb U^2)M^{-1}\mathfrak v\right>}
+ .
+\end{equation}
+We can thus compute $C_2$ using the solution $\mathbb U$ computed by \refname{sec:anyeq}{{\tt anyeq}}.
+
+\subsection{\tt simpleq-hardcore}\label{sec:simpleq-hardcore}
+\indent
+This method is used to solve the Simple equation with a hardcore potential:
+\begin{equation}
+ \left\{\begin{array}{>\displaystyle ll}
+ (-\Delta+4e) u(x)=2e\rho u\ast u(x)
+ &\mathrm{for\ }|x|>1\\
+ u(x)=1
+ &\mathrm{for\ }|x|\leqslant1
+ \end{array}\right.
+ \label{linearhc}
+\end{equation}
+with
+\begin{equation}
+ e=-\frac{4\pi\rho\partial u|_{|x|\searrow 1}}{2(1-\frac83\pi\rho+\rho^2\int_{|x|<1}dx\ u\ast u(x))}
+ .
+ \label{hardcore_energy}
+\end{equation}
+\bigskip
+
+This equation is solved in $x$-space, and as such is very different from \refname{sec:easyeq}{{\tt easyeq}}, and significantly longer to run.
+\bigskip
+
+\subsubsection{Usage}
+\indent
+Unless otherwise noted, this method takes the following parameters (specified via the {\tt [-p params]} flag, as a `{\tt;}' separated list of entries).
+\begin{itemize}
+ \item\makelink{param:simpleq-hardcore_rho}{}
+ {\tt rho} ({\tt Float64}, default: $10^{-6}$): density $\rho$.
+
+ \item\makelink{param:simpleq-hardcore_tolerance}{}
+ {\tt tolerance} ({\tt Float64}, default: $10^{-11}$): maximal size of final step in Newton iteration.
+
+ \item\makelink{param:simpleq-hardcore_maxiter}{}
+ {\tt maxiter} ({\tt Int64}, default: 21): maximal number of iterations of the Newton algorithm before giving up.
+
+ \item\makelink{param:simpleq-hardcore_P}{}
+ {\tt P} ({\tt Int64}, default: 11): order of all Chebyshev polynomial expansions (denoted by $P$ below).
+
+ \item\makelink{param:simpleq-hardcore_N}{}
+ {\tt N} ({\tt Int64}, default: 12): order of all Gauss quadratures (denoted by $N$ below).
+
+ \item\makelink{param:simpleq-hardcore_J}{}
+ {\tt J} ({\tt Int64}, default: 10): number of splines (denoted by $J$ below).
+\end{itemize}
+\bigskip
+
+The available {\tt commands} are the following.
+
+\begin{itemize}
+ \item\makelink{command:simpleq-hardcore_energy_rho}{}
+ {\tt energy\_rho}: compute the energy $e$ as a function of $\rho$.\par
+ \underline{Disabled parameters}: \refname{param:simpleq-hardcore_rho}{{\tt rho}}.\par
+ \underline{Extra parameters}:
+ \begin{itemize}
+ \item\makelink{param:simpleq-hardcore_minlrho}{}
+ {\tt minlrho} ({\tt Float64}, default: $10^{-6}$): minimal value for $\log_{10}\rho$.
+
+ \item\makelink{param:simpleq-hardcore_maxlrho}{}
+ {\tt maxlrho} ({\tt Float64}, default: $10^{2}$): maximal value for $\log_{10}\rho$.
+
+ \item\makelink{param:simpleq-hardcore_nlrho}{}
+ {\tt nlrho} ({\tt Int64}, default: $100$): number of values for $\rho$ (spaced logarithmically).
+
+ \item\makelink{param:simpleq-hardcore_rhos}{}
+ {\tt rhos} ({\tt Array\{Float64\}}, default: $(10^{{\tt minlrho}+\frac{{\tt maxlrho}-{\tt minlrho}}{{\tt nlrho}}n})_n$: list of values for $\rho$, specified as a `{\tt,}' separated list.
+ \end{itemize}
+ \underline{Output} (one line for each value of $\rho$): [$\rho$] [$e$] [Newton error $\epsilon$].\par
+ \underline{Multithread support}: yes, different values of $\rho$ split up among workers.
+
+ \item\makelink{command:simpleq-hardcore_condensate_fraction_rho}{}
+ {\tt condensate\_fraction\_rho}: compute the uncondensed fraction $\eta$ as a function of $\rho$.\par
+ \underline{Disabled parameters}: same as \refname{command:simpleq-hardcore_energy_rho}{{\tt energy\_rho}}.\par
+ \underline{Extra parameters}: same as \refname{command:simpleq-hardcore_energy_rho}{{\tt energy\_rho}}.\par
+ \underline{Output} (one line for each value of $\rho$): [$\rho$] [$\eta$] [Newton error $\epsilon$].\par
+ \underline{Multithread support}: yes, different values of $\rho$ split up among workers.
+
+ \item\makelink{command:simpleq-hardcore_ux}{}
+ {\tt ux}: compute $u$ as a function of $|x|$.\par
+ \underline{Extra parameters}:
+ \begin{itemize}
+ \item\makelink{param:simpleq-hardcore_xmin}{}
+ {\tt xmin} ({\tt Float64}, default: 0): minimum of the range of $|x|$ to be printed.
+
+ \item\makelink{param:simpleq-hardcore_xmax}{}
+ {\tt xmax} ({\tt Float64}, default: 100): maximum of the range of $|x|$ to be printed.
+
+ \item\makelink{param:simpleq-hardcore_nx}{}
+ {\tt nx} ({\tt Int64}, default: 100): number of points to print (linearly spaced).
+
+ \end{itemize}
+ \underline{Output} (one line for each value of $x$): [$|x|$] [$u(|x|)$]
+
+\end{itemize}
+
+\subsubsection{Description}
+\indent
+In order to carry out the computation of the solution of\-~(\ref{linearhc}) and compute the condensate fraction at the same time, we will consider the equation with an added parameter $\mu>0$:
+\begin{equation}
+ (-\Delta+4\epsilon)u=2e\rho u\ast u
+ ,\quad
+ \epsilon:=e+\frac\mu2
+ \label{hardcore_simple}
+\end{equation}
+for $|x|>1$.
+\bigskip
+
+\point{\bf Energy.}
+To compute the energy $e$ of this equation, with the extra parameter $\mu$, we consider the limit of the soft sphere potential $\lambda\mathds 1_{|x|<1}$ (see\-~(\ref{easyeq}) with $\beta_K=\beta_L=0$):
+\begin{equation}
+ (-\Delta+2\mu+4e)u(x)=s_\lambda(x)+2e\rho u\ast u
+ ,\quad
+ s_\lambda(x):=\lambda(1-u(x))\mathds 1_{|x|\leqslant 1}
+ ,\quad
+ \frac{2e}\rho=\int dx\ s_\lambda(x)
+ .
+\end{equation}
+Furthermore, since $\partial u$ need not be continuous at $|x|=1$, by integrating $-\Delta u$ over a thin spherical shell of radius 1, we find that, for $|x|\leqslant 1$,
+\begin{equation}
+ -\Delta u(x)=-\delta(|x|-1)\partial u|_{|x|\searrow1}
+\end{equation}
+so, formally,
+\begin{equation}
+ s_\infty(x)=\mathds 1_{|x|\leqslant 1}(2e(2-\rho u\ast u(x))+2\mu)-\delta(|x|-1)\partial u|_{|x|\searrow1}
+\end{equation}
+and
+\begin{equation}
+ \frac{2e}\rho=\int dx\ s_\infty(x)
+ =
+ 2e\left(\frac{8\pi}3-\rho\int_{|x|<1}u\ast u(x)\right)+\frac{8\pi}3\mu-4\pi\partial u|_{|x|\searrow1}
+ .
+\end{equation}
+Therefore,
+\begin{equation}
+ e=\frac{2\pi\rho(\frac23\mu-\partial u|_{|x|\searrow1})}{1-\frac{8\pi}3\rho+\rho^2\int_{|x|<1}dx\ u\ast u(x)}
+ .
+ \label{emu}
+\end{equation}
+\bigskip
+
+\point{\bf Integral equation.}
+We turn the differential equation in\-~(\ref{hardcore_simple}) into an integral equation.
+Let
+\begin{equation}
+ w(|x|):=|x|u(x)
+\end{equation}
+we have, for $r>1$,
+\begin{equation}
+ (-\partial_r^2+4\epsilon)w(r)=2e\rho ru\ast u(r)
+ .
+\end{equation}
+Furthermore, the bounded solution of
+\begin{equation}
+ (-\partial_r^2+\alpha^2)w(r)=F(r)
+ ,\quad
+ w(1)=1
+\end{equation}
+is
+\begin{equation}
+ w(r)=e^{-\alpha(r-1)}+\int_0^\infty ds\ \frac{F(s+1)}{2\alpha}\left(e^{-\alpha|(r-1)-s|}-e^{-\alpha((r-1)+s)}\right)
+ \label{solw}
+\end{equation}
+so, for $r>1$,
+\begin{equation}
+ u(r)=
+ \frac 1re^{-2\sqrt\epsilon(r-1)}
+ +
+ \frac{\rho e}{2r\sqrt\epsilon}\int_0^\infty ds\ (s+1)(u\ast u(s+1))\left(e^{-2\sqrt\epsilon|(r-1)-s|}-e^{-2\sqrt\epsilon((r-1)+s)}\right)
+ .
+\end{equation}
+In order to compute the integral more easily, we split it:
+\begin{equation}
+ \begin{largearray}
+ u(r)=
+ \frac 1re^{-2\sqrt\epsilon(r-1)}
+ +
+ \frac{\rho e}{r\sqrt\epsilon}\int_0^{r-1} ds\ (s+1)(u\ast u(s+1))\sinh(2\sqrt\epsilon s)e^{-2\sqrt\epsilon(r-1)}
+ \\[0.5cm]\hfill
+ +
+ \frac{\rho e}{r\sqrt\epsilon}\sinh(2\sqrt\epsilon(r-1))\int_{r-1}^\infty ds\ (s+1)(u\ast u(s+1))e^{-2\sqrt\epsilon s}
+ .
+ \end{largearray}
+\end{equation}
+We change variables in the last integral:
+\begin{equation}
+ \begin{largearray}
+ u(r)=
+ \frac 1re^{-2\sqrt\epsilon(r-1)}
+ +
+ \frac{\rho e}{r\sqrt\epsilon}\int_0^{r-1} ds\ (s+1)(u\ast u(s+1))\sinh(2\sqrt\epsilon s)e^{-2\sqrt\epsilon(r-1)}
+ \\[0.5cm]\hfill
+ +
+ \frac{\rho e}{2r\sqrt\epsilon}\left(1-e^{-4\sqrt\epsilon(r-1)}\right)\int_0^\infty d\sigma\ (\sigma+r)(u\ast u(\sigma+r))e^{-2\sqrt\epsilon\sigma}
+ .
+ \end{largearray}
+ \label{uinteq}
+\end{equation}
+\bigskip
+
+\point{\bf The auto-convolution term.} We split
+\begin{equation}
+ u(r)=\mathds 1_{r>1}u_+(r-1)+\mathds 1_{r\leqslant 1}
+ .
+\end{equation}
+in terms of which
+\begin{equation}
+ u\ast u=
+ \mathds 1_{r\leqslant 1}\ast\mathds 1_{r\leqslant 1}
+ +2\mathds 1_{r\leqslant 1}\ast(u_+(r-1)\mathds 1_{r>1})
+ +(\mathds 1_{r>1}u_+(r-1))\ast(u_+(r-1)\mathds 1_{r>1})
+ \label{u*u_dcmp}
+\end{equation}
+In bipolar coordinates (see lemma\-~\ref{lemma:bipolar}),
+\begin{equation}
+ \mathds 1_{r\leqslant 1}\ast\mathds 1_{r\leqslant 1}(r)
+ =
+ \frac{2\pi}{r}\int_0^1 dt\ t\int_{|r-t|}^{r+t}ds\ s\mathds 1_{s\leqslant 1}
+ \label{1*1}
+\end{equation}
+and, if $r\geqslant 0$ and $t\geqslant 0$, then
+\begin{equation}
+ \int_{|r-t|}^{r+t}ds\ s\mathds 1_{s\leqslant 1}
+ =
+ \mathds 1_{r-1\leqslant t\leqslant r+1}\int_{|r-t|}^{\min(1,r+t)}ds\ s
+ =
+ \mathds 1_{r-1\leqslant t\leqslant r+1}
+ \left(
+ \mathds 1_{t\leqslant 1-r}
+ 2rt
+ +
+ \mathds 1_{t>1-r}
+ \frac{1-(r-t)^2}2
+ \right)
+ .
+ \label{int1}
+\end{equation}
+Therefore, if $r\geqslant 1$
+\begin{equation}
+ \mathds 1_{r\leqslant 1}\ast\mathds 1_{r\leqslant 1}(r)
+ =
+ \mathds 1_{r\leqslant 2}
+ \frac{2\pi}{r}\int_{r-1}^1 dt\ t
+ \frac{1-(r-t)^2}2
+ =
+ \mathds 1_{r\leqslant 2}\frac\pi{12}(r-2)^2(r+4)
+ \label{u*u_1}
+\end{equation}
+and if $r<1$,
+\begin{equation}
+ \mathds 1_{r\leqslant 1}\ast\mathds 1_{r\leqslant 1}(r)
+ =
+ \frac{2\pi}r\int_0^1dt\ t
+ \left(
+ \mathds 1_{t\leqslant 1-r}
+ 2rt
+ +
+ \mathds 1_{t>1-r}
+ \frac{1-(r-t)^2}2
+ \right)
+\end{equation}
+so
+\begin{equation}
+ \mathds 1_{r\leqslant 1}\ast\mathds 1_{r\leqslant 1}(r)
+ =\frac43\pi(1-r)^3
+ +\frac\pi{12}r(36-48r+17r^2)
+ =
+ \frac\pi{12}(r-2)^2(r+4)
+ .
+\end{equation}
+Thus, (\ref{u*u_1}) holds for all $r$.
+Furthermore,
+\begin{equation}
+ 2\mathds 1_{r\leqslant 1}\ast(u_+(r-1)\mathds 1_{r>1})
+ =
+ \frac{4\pi}{r}\int_1^\infty dt\ tu_+(t-1)\int_{|r-t|}^{r+t}ds\ s\mathds 1_{s\leqslant 1}
+\end{equation}
+so, if $r\geqslant 0$ then, by\-~(\ref{int1}),
+\begin{equation}
+ 2\mathds 1_{r\leqslant 1}\ast(u_+(r-1)\mathds 1_{r>1})(r)
+ =
+ \frac{2\pi}{r}\int_{\max(1,r-1)}^{r+1} dt\ tu_+(t-1)(1-(r-t)^2)
+ .
+ \label{u*u_cross}
+\end{equation}
+Finally, if $r\geqslant 0$ then
+\begin{equation}
+ (\mathds 1_{r>1}u_+(r-1))\ast(u_+(r-1)\mathds 1_{r>1})(r)
+ =
+ \frac{2\pi}{r}\int_1^\infty dt\ tu_+(t-1)\int_{\max{(1,|r-t|)}}^{r+t}ds\ su_+(s-1)
+ .
+ \label{u*u_u}
+\end{equation}
+Thus, by~\-(\ref{u*u_1}), (\ref{u*u_cross}) and\-~(\ref{u*u_u}), for $r\geqslant -1$,
+\begin{equation}
+ \begin{largearray}
+ u\ast u(1+r)=
+ \mathds 1_{r\leqslant 1}\frac\pi{12}(r-1)^2(r+5)
+ +
+ \frac{2\pi}{r+1}\int_{\max(0,r-1)}^{r+1} dt\ (t+1)u_+(t)(1-(r-t)^2)
+ \\[0.5cm]\hfill
+ +
+ \frac{2\pi}{r+1}\int_0^\infty dt\ (t+1)u_+(t)\int_{\max{(0,|r-t|-1)}}^{r+t+1}ds\ (s+1)u_+(s)
+ .
+ \end{largearray}
+\end{equation}
+We then compactify the integrals by changing variables to $\tau=\frac{1-t}{1+t}$ and $\sigma=\frac{1-s}{1+s}$:
+\begin{equation}
+ \begin{largearray}
+ u\ast u(1+r)=
+ \mathds 1_{r\leqslant 1}\frac\pi{12}(r-1)^2(r+5)
+ +
+ \frac{8\pi}{r+1}\int_{-\frac r{2+r}}^{\min(1,\frac{2-r}r)} d\tau\ \frac1{(1+\tau)^3}u_+({\textstyle\frac{1-\tau}{1+\tau}})(1-(r-{\textstyle\frac{1-\tau}{1+\tau}})^2)
+ \\[0.5cm]\hfill
+ +
+ \frac{32\pi}{r+1}\int_{-1}^1 d\tau\ \frac1{(1+\tau)^3}u_+({\textstyle\frac{1-\tau}{1+\tau}})\int_{\alpha_-(1+r,\tau)}^{\min(1,\beta_+(r,\tau))}d\sigma\ \frac1{(1+\sigma)^3}u_+({\textstyle\frac{1-\sigma}{1+\sigma}})
+ .
+ \end{largearray}
+ \label{u*u}
+\end{equation}
+with
+\begin{equation}
+ \alpha_-(1+r,\tau):=\frac{-r-\frac{1-\tau}{1+\tau}}{2+r+\frac{1-\tau}{1+\tau}}
+ ,\quad
+ \beta_+(r,\tau):=\frac{2-|r-\frac{1-\tau}{1+\tau}|}{|r-\frac{1-\tau}{1+\tau}|}
+\end{equation}
+(note that $\alpha_-$ is the same as defined for fulleq).
+Finally, note that, if $\beta_+<1$, that is, if $|r-\frac{1-\tau}{1+\tau}|>1$, then
+\begin{equation}
+ \beta_+(r,\tau)=\alpha_+({\textstyle |r-\frac{1-\tau}{1+\tau}|-1+\frac{1-\tau}{1+\tau}},\tau)
+\end{equation}
+where
+\begin{equation}
+ \alpha_+(r,\tau):=\frac{1-|r-\frac{1-\tau}{1+\tau}|}{1+|r-\frac{1-\tau}{1+\tau}|}
+\end{equation}
+is the same as is defined for \refname{sec:anyeq}{{\tt anyeq}} (\ref{anyeq_alpha}).
+\bigskip
+
+\point{\bf Chebyshev polynomial expansion.} We use the same interpolation as we used in \refname{sec:anyeq}{{\tt anyeq}}: (\ref{a_chebyshev_spline})
+\begin{equation}
+ \frac1{(1+\tau)^{\nu_u}}u_+({\textstyle\frac{1-\tau}{1+\tau}})=\sum_{l=0}^{J-1}\mathds 1_{\tau_l\leqslant\tau<\tau_{l+1}}\sum_{n=0}^\infty \mathbf F_{l,n}^{(\nu_u)}(u_+) T_n({\textstyle\frac{2\tau-(\tau_l+\tau_{l+1})}{\tau_{l+1}-\tau_l}})
+ \label{a_chebyshev_spline}
+\end{equation}
+($J$ is set by the parameter \refname{param:simpleq-hardcore_J}{{\tt J}})
+with
+\begin{equation}
+ \mathbf F_{l,n}^{(\nu_u)}(u_+):=
+ \frac{2-\delta_{n,0}}{\pi}
+ \int_0^{\pi} d\theta\
+ \frac{\cos(n\theta)}{(1+\frac{\tau_{l+1}-\tau_l}2\cos(\theta)+\frac{\tau_{l+1}+\tau_l}2)^{\nu_u}}
+ u_+({\textstyle\frac{2-(\tau_{l+1}-\tau_l)\cos(\theta)-(\tau_{l+1}+\tau_\alpha)}{2+(\tau_{l+1}-\tau_l)\cos(\theta)+(\tau_{l+1}+\tau_l)}})
+ \label{bfF}
+\end{equation}
+and we take $\nu_u$ to be the decay exponent of $u$, which we will assume is $\nu_u=4$.
+In particular, by\-~(\ref{u*u}),
+\begin{equation}
+ u\ast u(1+r)=\mathds 1_{r\leqslant 1}B^{(0)}(r)+\sum_l\sum_n\mathbf F_{l,n}^{(\nu_u)}(u_+)B^{(1)}_{l,n}(r)+\sum_{l,l'}\sum_{n,m}\mathbf F_{l,n}^{(\nu_u)}(u_+)\mathbf F_{l',m}^{(\nu_u)}(u_+)B^{(2)}_{l,n;l',m}(r)
+ \label{u*u}
+\end{equation}
+with
+\begin{equation}
+ B^{(0)}(r):=
+ \frac\pi{12}(r-1)^2(r+5)
+\end{equation}
+\begin{equation}
+ B^{(1)}_{l,n}(r):=
+ \mathds 1_{\tau_l<\frac{2-r}r}\mathds 1_{\tau_{l+1}>-\frac r{2+r}}
+ \frac{8\pi}{r+1}\int_{\max(\tau_l,-\frac r{2+r})}^{\min(\tau_{l+1},\frac{2-r}r)} d\tau\ \frac1{(1+\tau)^{3-\nu_u}}(1-(r-{\textstyle\frac{1-\tau}{1+\tau}})^2)T_n({\textstyle\frac{2\tau-(\tau_l+\tau_{l+1})}{\tau_{l+1}-\tau_l}})
+\end{equation}
+\begin{equation}
+ \begin{largearray}
+ B^{(2)}_{l,n;l',m}(r):=
+ \frac{32\pi}{r+1}\int_{\tau_l}^{\tau_{l+1}} d\tau\ \frac1{(1+\tau)^{3-\nu_u}}T_n({\textstyle\frac{2\tau-(\tau_l+\tau_{l+1})}{\tau_{l+1}-\tau_l}})
+ \mathds 1_{\tau_{l'}<\alpha_+(|r-\frac{1-\tau}{1+\tau}|-\frac{2\tau}{1+\tau},\tau)}\mathds 1_{\tau_{l'+1}>\alpha_-(1+r,\tau)}
+ \cdot\\[0.5cm]\hfill\cdot
+ \int_{\max(\tau_{l'},\alpha_-(1+r,\tau))}^{\min(\tau_{l'+1},\alpha_+(|r-\frac{1-\tau}{1+\tau}|-\frac{2\tau}{1+\tau},\tau))}d\sigma\ \frac1{(1+\sigma)^{3-\nu_u}}T_m({\textstyle\frac{2\sigma-(\tau_{l'}+\tau_{l'+1})}{\tau_{l'+1}-\tau_{l'}}})
+ .
+ \end{largearray}
+\end{equation}
+Thus, by\-~(\ref{uinteq}), for $r>0$,
+\begin{equation}
+ u_+(r,e,\epsilon)=
+ D^{(0)}(r,e,\epsilon)
+ +
+ \sum_l\sum_n\mathbf F_{l,n}^{(\nu_u)}(u_+)D^{(1)}_{l,n}(r,e,\epsilon)
+ +
+ \sum_{l,l'}\sum_{n,m}\mathbf F_{l,n}^{(\nu_u)}(u_+)\mathbf F_{l',m}^{(\nu_u)}(u_+)D^{(2)}_{l,n;l',m}(r,e,\epsilon)
+ \label{hardcore_u+}
+\end{equation}
+with
+\begin{equation}
+ \begin{largearray}
+ D^{(0)}(r,e,\epsilon):=
+ \frac 1{r+1}e^{-2\sqrt\epsilon r}
+ +
+ \frac{\rho e}{(r+1)\sqrt\epsilon}\int_0^{\min(1,r)} ds\ (s+1)B^{(0)}(s)\sinh(2\sqrt\epsilon s)e^{-2\sqrt\epsilon r}
+ \\[0.5cm]\hfill
+ +
+ \mathds 1_{r\leqslant 1}
+ \frac{\rho e}{2(r+1)\sqrt\epsilon}\left(1-e^{-4\sqrt\epsilon r}\right)\int_0^{1-r} d\sigma\ (\sigma+r+1)B^{(0)}(\sigma+r)e^{-2\sqrt\epsilon\sigma}
+ \end{largearray}
+ \label{D0}
+\end{equation}
+\begin{equation}
+ \begin{largearray}
+ D^{(1)}_{l,n}(r,e,\epsilon):=
+ \frac{\rho e}{(r+1)\sqrt\epsilon}\int_0^r ds\ (s+1)B^{(1)}_{l,n}(s)\sinh(2\sqrt\epsilon s)e^{-2\sqrt\epsilon r}
+ \\[0.5cm]\hfill
+ +
+ \frac{\rho e}{2(r+1)\sqrt\epsilon}\left(1-e^{-4\sqrt\epsilon r}\right)\int_0^\infty d\sigma\ (\sigma+r+1)B_{l,n}^{(1)}(\sigma+r)e^{-2\sqrt\epsilon\sigma}
+ .
+ \end{largearray}
+ \label{D1}
+\end{equation}
+and
+\begin{equation}
+ \begin{largearray}
+ D^{(2)}_{l,n;l',m}(r,e,\epsilon):=
+ \frac{\rho e}{(r+1)\sqrt\epsilon}\int_0^r ds\ (s+1)B^{(2)}_{l,n;l',m}(s)\sinh(2\sqrt\epsilon s)e^{-2\sqrt\epsilon r}
+ \\[0.5cm]\hfill
+ +
+ \frac{\rho e}{2(r+1)\sqrt\epsilon}\left(1-e^{-4\sqrt\epsilon r}\right)\int_0^\infty d\sigma\ (\sigma+r+1)B_{l,n;l',m}^{(2)}(\sigma+r)e^{-2\sqrt\epsilon\sigma}
+ .
+ \end{largearray}
+ \label{D2}
+\end{equation}
+\bigskip
+
+\point{\bf Energy.} We now compute the approximation for the energy, using\-~(\ref{hardcore_energy}).
+\bigskip
+
+\subpoint We start with $\partial u|_{|x|\searrow 1}$.
+By\-~(\ref{uinteq}),
+\begin{equation}
+ \partial u|_{|x|\searrow 1}
+ =
+ -(1+2\sqrt\epsilon)
+ +
+ 2\rho e\int_0^\infty d\sigma\ (\sigma+1)(u\ast u(\sigma+1))e^{-2\sqrt\epsilon\sigma}
+\end{equation}
+\bigskip
+which, by\-~(\ref{u*u}), becomes
+\begin{equation}
+ \begin{largearray}
+ \partial u|_{|x|\searrow 1}
+ =
+ -(1+2\sqrt\epsilon)
+ +
+ \gamma^{(0)}(e,\epsilon)
+ +
+ \sum_l\sum_n\mathbf F_{l,n}^{(\nu_u)}(u_+)\gamma^{(1)}_{l,n}(e,\epsilon)
+ +\\\hfill+
+ \sum_{l,l'}\sum_{n,m}\mathbf F_{l,n}^{(\nu_u)}(u_+)\mathbf F_{l',m}^{(\nu_u)}(u_+)\gamma^{(2)}_{l,n;l',m}(e,\epsilon)
+ \end{largearray}
+\end{equation}
+with
+\begin{equation}
+ \gamma^{(0)}(e,\epsilon):=
+ 2\rho e\int_0^1 d\sigma\ (\sigma+1)B^{(0)}(\sigma)e^{-2\sqrt\epsilon\sigma}
+\end{equation}
+\begin{equation}
+ \gamma^{(1)}_{l,n}(e,\epsilon):=
+ 2\rho e\int_0^\infty d\sigma\ (\sigma+1)B_{l,n}^{(1)}(\sigma)e^{-2\sqrt\epsilon\sigma}
+\end{equation}
+and
+\begin{equation}
+ \gamma^{(2)}_{l,n;l',m}(e,\epsilon):=
+ 2\rho e\int_0^\infty d\sigma\ (\sigma+1)B_{l,n;l',m}^{(2)}(\sigma)e^{-2\sqrt\epsilon\sigma}
+ .
+\end{equation}
+
+\subpoint Let us now turn to $\int_{|x|<1}dx\ u\ast u(x)$.
+We have
+\begin{equation}
+ \int_{|x|<1}dx\ u\ast u(x)
+ =
+ 4\pi\int_0^1 dr\ r^2 u\ast u(r)
+\end{equation}
+so, by\-~(\ref{u*u}),
+\begin{equation}
+ \int_{|x|<1}dx\ u\ast u(x)
+ =
+ \bar\gamma^{(0)}(r)
+ +
+ \sum_l\sum_n\mathbf F_{l,n}^{(\nu_u)}(u_+)\bar\gamma^{(1)}_{l,n}(r)
+ +
+ \sum_{l,l'}\sum_{n,m}\mathbf F_{l,n}^{(\nu_u)}(u_+)\mathbf F_{l',m}^{(\nu_u)}(u_+)\bar\gamma^{(2)}_{l,n;l',m}(r)
+ \label{intusu}
+\end{equation}
+with
+\begin{equation}
+ \bar\gamma^{(0)}:=
+ 4\pi\int_0^1 d\sigma\ \sigma^2B^{(0)}(\sigma-1)
+\end{equation}
+\begin{equation}
+ \bar\gamma^{(1)}_{l,n}:=
+ 4\pi\int_0^1 d\sigma\ \sigma^2B_{l,n}^{(1)}(\sigma-1)
+\end{equation}
+and
+\begin{equation}
+ \bar\gamma^{(2)}_{l,n;l',m}:=
+ 4\pi\int_0^1 d\sigma\ \sigma^2B_{l,n;l',m}^{(2)}(\sigma-1)
+ .
+\end{equation}
+\bigskip
+
+\subpoint Thus,
+\begin{equation}
+ \begin{largearray}
+ e=2\pi\rho
+ \cdot\\\hfill\cdot
+ \frac
+ {
+ C(\epsilon)
+ -
+ \gamma^{(0)}(e,\epsilon)
+ -
+ \sum_l\sum_n\mathbf F_{l,n}^{(\nu_u)}(u_+)\gamma^{(1)}_{l,n}(e,\epsilon)
+ -
+ \sum_{l,l'}\sum_{n,m}\mathbf F_{l,n}^{(\nu_u)}(u_+)\mathbf F_{l',m}^{(\nu_u)}(u_+)\gamma^{(2)}_{l,n;l',m}(e,\epsilon)
+ }
+ {1-\frac83\pi\rho+\rho^2\left(
+ \bar\gamma^{(0)}
+ +
+ \sum_l\sum_n\mathbf F_{l,n}^{(\nu_u)}(u_+)\bar\gamma^{(1)}_{l,n}
+ +
+ \sum_{l,l'}\sum_{n,m}\mathbf F_{l,n}^{(\nu_u)}(u_+)\mathbf F_{l',m}^{(\nu_u)}(u_+)\bar\gamma^{(2)}_{l,n;l',m}
+ \right)}
+ .
+ \end{largearray}
+\end{equation}
+\begin{equation}
+ C(\epsilon):=\frac23\mu+(1+2\sqrt\epsilon)
+ =\frac43(\epsilon-e)+1+2\sqrt\epsilon
+\end{equation}
+\bigskip
+
+\point{\bf Newton algorithm.}
+In this paragraph, we set $\epsilon=e$, that is, $\mu=0$.
+\bigskip
+
+\subpoint
+As we did for \refname{sec:anyeq}{{\tt anyeq}}, we discretize the integral in\-~(\ref{bfF}) by using a Gauss-Legendre quadrature, and truncate the sum over Chebyshev polynomials to order \refname{param:simpleq-hardcore_P}{{\tt P}}.
+We then reduce the computation to a finite system of equations, whose variables are
+\begin{equation}
+ e
+ ,\quad
+ \mathfrak u_{l,j}:=u_+(r_{l,j})
+ ,\quad
+ r_{l,j}:=
+ \frac{2+(\tau_{l+1}-\tau_l)\sin(\frac{\pi x_j}2)-(\tau_{l+1}+\tau_\alpha)}{2-(\tau_{l+1}-\tau_l)\sin(\frac{\pi x_j}2)+(\tau_{l+1}+\tau_l)}
+\end{equation}
+where $x_j$ are the abcissa for Gauss-Legendre quadratures (see\-~(\ref{klj})).
+In other words, we define a vector $\mathbb U$ in dimension \refname{param:simpleq-hardcore_N}{{\tt N}}$\times$\refname{param:simpleq-hardcore_J}{{\tt J}}$+1$, where the first \refname{param:simpleq-hardcore_N}{{\tt N}}$\times$\refname{param:simpleq-hardcore_J}{{\tt J}} terms are $\mathfrak u_{l,j}$ and the last component is $e$.
+We then write\-~(\ref{hardcore_u+}) as, for $l\in\{0,\cdots,J-1\}$, $j\in\{1,\cdots,N\}$,
+\begin{equation}
+ \Xi_{lN+j}(\mathbb U)=0
+ ,\quad
+ \Xi_{NJ+1}(\mathbb U)=0
+\end{equation}
+(note that $\Xi_{lN+j}$ corresponds to the pair $(l,j)$)
+with
+\begin{equation}
+ \begin{largearray}
+ \Xi_{lN+j}(\mathbb U):=
+ -\mathfrak u_{l,j}
+ +
+ \mathbb D^{(0)}(r_{l,j},e)
+ +
+ \sum_{l'}\sum_n\mathfrak F_{l',n}^{(\nu_u)}(\mathfrak u)\mathbb D^{(1)}_{l',n}(r_{l,j},e)
+ +\\\hfill+
+ \sum_{l',l''}\sum_{n,m}\mathfrak F_{l',n}^{(\nu_u)}(\mathfrak u)\mathfrak F_{l'',m}^{(\nu_u)}(\mathfrak u)\mathbb D^{(2)}_{l',n;l'',m}(r_{l,j},e)
+ \end{largearray}
+\end{equation}
+\begin{equation}
+ \begin{largearray}
+ \Xi_{NJ+1}(\mathbb U):=-e
+ +\\\hfill+
+ 2\pi\rho
+ \frac
+ {
+ C(e)
+ -
+ \mathfrak g^{(0)}(e)
+ -
+ \sum_l\sum_n\mathfrak F_{l,n}^{(\nu_u)}(\mathfrak u)\mathfrak g^{(1)}_{l,n}(e)
+ -
+ \sum_{l,l'}\sum_{n,m}\mathfrak F_{l,n}^{(\nu_u)}(\mathfrak u)\mathfrak F_{l',m}^{(\nu_u)}(\mathfrak u)\mathfrak g^{(2)}_{l,n;l',m}(e)
+ }
+ {1-\frac83\pi\rho+\rho^2\left(
+ \bar{\mathfrak g}^{(0)}
+ +
+ \sum_l\sum_n\mathfrak F_{l,n}^{(\nu_u)}(\mathfrak u)\bar{\mathfrak g}^{(1)}_{l,n}
+ +
+ \sum_{l,l'}\sum_{n,m}\mathfrak F_{l,n}^{(\nu_u)}(\mathfrak u)\mathfrak F_{l',m}^{(\nu_u)}(\mathfrak u)\bar{\mathfrak g}^{(2)}_{l,n;l',m}
+ \right)}
+ .
+ \end{largearray}
+\end{equation}
+where $\mathfrak F$ is defined in\-~(\ref{frakF}), and $\mathbb D^{(i)}$, $\mathfrak g^{(i)}$, $\bar{\mathfrak g}^{(i)}$ are defined like $D^{(i)}$, $\gamma^{(i)}$ and $\bar\gamma^{(i)}$ except that the integrals over bounded intervals are approximated using Gauss-Legendre quadratures, and the integrals from $0$ to $\infty$ are approximated using Gauss-Laguerre quadratures.
+Gauss-Legendre and Gauss-Laguerre quadratures and their errors are discussed in appendix\-~\ref{appGL}.
+The orders of the quadratures are given by the variable \refname{param:simpleq-hardcore_N}{{\tt N}}.
+\bigskip
+
+\subpoint
+We then solve $\Xi=0$ using the Newton algorithm, that is, we define a sequence of $\mathbb U$'s:
+\begin{equation}
+ \mathbb U^{(n+1)}=\mathbb U^{(n)}-(D\Xi(\mathbb U^{(n)}))^{-1}\Xi(\mathbb U^{(n)})
+\end{equation}
+where $D\Xi$ is the Jacobian of $\Xi$:
+\begin{equation}
+ (D\Xi)_{\alpha,\beta}:=\frac{\partial\Xi_\alpha}{\partial\mathbb U_\beta}
+ .
+\end{equation}
+We initialize the algorithm with
+\begin{equation}
+ \mathbb U^{(0)}_{lN+j}=\frac1{(1+r_{l,j}^2)^2}
+ ,\quad
+ \mathbb U^{(0)}_{JN+1}=\pi\rho
+ .
+\end{equation}
+\bigskip
+
+\subpoint
+We are left with computing the Jacobian of $\Xi$:
+\begin{equation}
+ \begin{largearray}
+ \frac{\partial\Xi_{lN+j}(\mathbb U)}{\partial\mathfrak u_{l',i}}=
+ -\delta_{l,l'}\delta_{j,i}
+ +
+ \sum_{l''}\sum_n\mathfrak F_{l'',n}^{(\nu_u)}(\mathds 1_{l',i})\mathbb D^{(1)}_{l'',n}(r_{l,j},e)
+ +\\\hfill+
+ 2\sum_{l'',l'''}\sum_{n,m}\mathfrak F_{l'',n}^{(\nu_u)}(\mathfrak u)\mathfrak F_{l''',m}^{(\nu_u)}(\mathds 1_{l',j})\mathbb D^{(2)}_{l'',n;l''',m}(r_{l,j},e)
+ \end{largearray}
+\end{equation}
+where $\mathds 1_{l',i}$ is a vector whose only non-vanishing entry is the $(l',i)$-th, which is 1,
+\begin{equation}
+ \begin{largearray}
+ \frac{\partial\Xi_{JN+1}(\mathbb U)}{\partial\mathfrak u_{l',i}}
+ =\\\hfill=
+ 2\pi\rho
+ \frac
+ {
+ -
+ \sum_l\sum_n\mathfrak F_{l,n}^{(\nu_u)}(\mathds 1_{l',i})\mathfrak g^{(1)}_{l,n}(e)
+ -
+ 2\sum_{l,l''}\sum_{n,m}\mathfrak F_{l,n}^{(\nu_u)}(\mathfrak u)\mathfrak F_{l'',m}^{(\nu_u)}(\mathds 1_{l',i})\mathfrak g^{(2)}_{l,n;l'',m}(e)
+ }
+ {1-\frac83\pi\rho+\rho^2\left(
+ \bar{\mathfrak g}^{(0)}
+ +
+ \sum_l\sum_n\mathfrak F_{l,n}^{(\nu_u)}(\mathfrak u)\bar{\mathfrak g}^{(1)}_{l,n}
+ +
+ \sum_{l,l''}\sum_{n,m}\mathfrak F_{l,n}^{(\nu_u)}(\mathfrak u)\mathfrak F_{l'',m}^{(\nu_u)}(\mathfrak u)\bar{\mathfrak g}^{(2)}_{l,n;l'',m}
+ \right)}
+ \\[1cm]\hfill
+ -(\Xi_{NJ+1}(\mathbb U)+e)
+ \frac
+ {\rho^2\left(
+ \sum_l\sum_n\mathfrak F_{l,n}^{(\nu_u)}(\mathds 1_{l'.i})\bar{\mathfrak g}^{(1)}_{l,n}
+ +
+ 2\sum_{l,l''}\sum_{n,m}\mathfrak F_{l,n}^{(\nu_u)}(\mathfrak u)\mathfrak F_{l'',m}^{(\nu_u)}(\mathds 1_{l',i})\bar{\mathfrak g}^{(2)}_{l,n;l'',m}
+ \right)}{1-\frac83\pi\rho+\rho^2\left(
+ \bar{\mathfrak g}^{(0)}
+ +
+ \sum_l\sum_n\mathfrak F_{l,n}^{(\nu_u)}(\mathfrak u)\bar{\mathfrak g}^{(1)}_{l,n}
+ +
+ \sum_{l,l''}\sum_{n,m}\mathfrak F_{l,n}^{(\nu_u)}(\mathfrak u)\mathfrak F_{l'',m}^{(\nu_u)}(\mathfrak u)\bar{\mathfrak g}^{(2)}_{l,n;l'',m}
+ \right)}
+ .
+ \end{largearray}
+\end{equation}
+\begin{equation}
+ \begin{largearray}
+ \frac{\partial\Xi_{lN+j}(\mathbb U)}{\partial e}=
+ \partial_e\mathbb D^{(0)}(r_{l,j},e)
+ +
+ \sum_{l'}\sum_n\mathfrak F_{l',n}^{(\nu_u)}(\mathfrak u)\partial_e\mathbb D^{(1)}_{l',n}(r_{l,j},e)
+ +\\\hfill+
+ \sum_{l',l''}\sum_{n,m}\mathfrak F_{l',n}^{(\nu_u)}(\mathfrak u)\mathfrak F_{l'',m}^{(\nu_u)}(\mathfrak u)\partial_e\mathbb D^{(2)}_{l',n;l'',m}(r_{l,j},e)
+ \end{largearray}
+\end{equation}
+\begin{equation}
+ \begin{largearray}
+ \frac{\partial\Xi_{NJ+1}(\mathbb U)}{\partial e}
+ =
+ -1
+ +\\\hfill+
+ 2\pi\rho
+ \frac
+ {
+ \partial_e C(e)
+ -
+ \partial_e\mathfrak g^{(0)}(e)
+ -
+ \sum_l\sum_n\mathfrak F_{l,n}^{(\nu_u)}(\mathfrak u)\partial_e\mathfrak g^{(1)}_{l,n}(e)
+ -
+ \sum_{l,l'}\sum_{n,m}\mathfrak F_{l,n}^{(\nu_u)}(\mathfrak u)\mathfrak F_{l',m}^{(\nu_u)}(\mathfrak u)\partial_e\mathfrak g^{(2)}_{l,n;l',m}(e)
+ }
+ {1-\frac83\pi\rho+\rho^2\left(
+ \bar{\mathfrak g}^{(0)}
+ +
+ \sum_l\sum_n\mathfrak F_{l,n}^{(\nu_u)}(\mathfrak u)\bar{\mathfrak g}^{(1)}_{l,n}
+ +
+ \sum_{l,l'}\sum_{n,m}\mathfrak F_{l,n}^{(\nu_u)}(\mathfrak u)\mathfrak F_{l',m}^{(\nu_u)}(\mathfrak u)\bar{\mathfrak g}^{(2)}_{l,n;l',m}
+ \right)}
+ .
+ \end{largearray}
+\end{equation}
+To compute $\partial_e\mathbb D^{(i)}$ and $\partial_e\mathfrak g^{(i)}$, we use $\partial_e=\frac1{2\sqrt e}\frac\partial{\partial\sqrt e}$ and
+\begin{equation}
+ \frac{\partial C(e)}{\partial\sqrt e}=2
+\end{equation}
+\begin{equation}
+ \begin{largearray}
+ \frac{\partial D^{(0)}(r,e)}{\partial\sqrt e}
+ =
+ -\frac{2r}{r+1}e^{-2\sqrt er}
+ \\[0.5cm]\hfill
+ +
+ \frac{\rho}{r+1}\int_0^{\min(1,r)} ds\ (s+1)B^{(0)}(s)e^{-2\sqrt er}\left(
+ (1-2\sqrt er)\sinh(2\sqrt e s)
+ +2\sqrt es\cosh(2\sqrt e s)
+ \right)
+ \\[0.5cm]
+ +
+ \mathds 1_{r\leqslant 1}
+ \frac{\rho}{2(r+1)}\int_0^{1-r} d\sigma\ (\sigma+r+1)B^{(0)}(\sigma+r)
+ \cdot\\[0.5cm]\hfill\cdot
+ \left(
+ (1-2\sqrt e\sigma)\left(1-e^{-4\sqrt er}\right)e^{-2\sqrt e\sigma}
+ +
+ 4\sqrt e re^{-2\sqrt e(2r+\sigma)}
+ \right)
+ \end{largearray}
+\end{equation}
+\begin{equation}
+ \begin{largearray}
+ \frac{\partial D_{l,n}^{(1)}(r,e)}{\partial\sqrt e}
+ =
+ \frac{\rho}{r+1}\int_0^{r} ds\ (s+1)B_{l,n}^{(1)}(s)e^{-2\sqrt er}\left(
+ (1-2\sqrt er)\sinh(2\sqrt e s)
+ +2\sqrt es\cosh(2\sqrt e s)
+ \right)
+ \\[0.5cm]
+ +
+ \frac{\rho}{2(r+1)}\int_0^\infty d\sigma\ (\sigma+r+1)B_{l,n}^{(1)}(\sigma+r)
+ \cdot\\[0.5cm]\hfill\cdot
+ \left(
+ (1-2\sqrt e\sigma)\left(1-e^{-4\sqrt er}\right)e^{-2\sqrt e\sigma}
+ +
+ 4\sqrt e re^{-2\sqrt e(2r+\sigma)}
+ \right)
+ \end{largearray}
+\end{equation}
+\begin{equation}
+ \begin{largearray}
+ \frac{\partial D_{l,n;l',m}^{(2)}(r,e)}{\partial\sqrt e}
+ \\[0.5cm]
+ =
+ \frac{\rho}{r+1}\int_0^{r} ds\ (s+1)B_{l,n;l',m}^{(2)}(s)e^{-2\sqrt er}\left(
+ (1-2\sqrt er)\sinh(2\sqrt e s)
+ +2\sqrt es\cosh(2\sqrt e s)
+ \right)
+ \\[0.5cm]
+ +
+ \frac{\rho}{2(r+1)}\int_0^\infty d\sigma\ (\sigma+r+1)B_{l,n;l',m}^{(2)}(\sigma+r)
+ \cdot\\[0.5cm]\hfill\cdot
+ \left(
+ (1-2\sqrt e\sigma)\left(1-e^{-4\sqrt er}\right)e^{-2\sqrt e\sigma}
+ +
+ 4\sqrt e re^{-2\sqrt e(2r+\sigma)}
+ \right)
+ .
+ \end{largearray}
+\end{equation}
+Furthermore,
+\begin{equation}
+ \frac{\partial\gamma^{(0)}(e)}{\partial\sqrt e}=
+ 4\rho\sqrt e\int_0^1 d\sigma\ (\sigma+1)B^{(0)}(\sigma)(1-\sqrt e\sigma)e^{-2\sqrt e\sigma}
+\end{equation}
+\begin{equation}
+ \frac{\partial\gamma^{(1)}_{l,n}(e)}{\partial\sqrt e}=
+ 4\rho e\int_0^\infty d\sigma\ (\sigma+1)B_{l,n}^{(1)}(\sigma)(1-\sqrt e\sigma)e^{-2\sqrt e\sigma}
+\end{equation}
+and
+\begin{equation}
+ \frac{\partial\gamma^{(2)}_{l,n;l',m}(e)}{\partial\sqrt e}=
+ 4\rho e\int_0^\infty d\sigma\ (\sigma+1)B_{l,n;l',m}^{(2)}(\sigma)(1-\sqrt e\sigma)e^{-2\sqrt e\sigma}
+ .
+\end{equation}
+Finally, to get from $D$ to $\mathbb D$ and $\gamma$ to $\mathfrak g$, we approximate the integrate using Gauss-Legendre and Gauss-Laguerre quadratures (see appendix\-~\ref{appGL}), as described above.
+\bigskip
+
+\subpoint
+We iterate the Newton algorithm until the Newton relative error $\epsilon$ becomes smaller than the \refname{param:easyeq_tolerance}{{\tt tolerance}} parameter.
+The Newton error is defined as
+\begin{equation}
+ \epsilon=\frac{\|\mathbb U^{(n+1)}-\mathbb U^{(n)}\|_2}{\|\mathbb U^{(n)}\|_2}
+\end{equation}
+where $\|\cdot\|_2$ is the $l_2$ norm.
+The energy thus obtained is
+\begin{equation}
+ e=\mathbb U_{JN+1}
+ .
+\end{equation}
+\bigskip
+
+\point{\bf Condensate fraction.}
+To compute the condensate fraction, we use the parameter $\mu$ in\-~(\ref{hardcore_simple}).
+The uncondensed fraction is
+\begin{equation}
+ \eta=\partial_\mu e|_{\mu=0}
+ .
+\end{equation}
+To compute $\partial_\mu e$, we use
+\begin{equation}
+ \Xi(\mathbb U)=0
+\end{equation}
+which we differentiate with respect to $\mu$:
+\begin{equation}
+ \partial_\mu\mathbb U=-(D\Xi)^{-1}\partial_\mu\Xi
+ .
+\end{equation}
+We are left with computing $\partial_\mu\Xi$:
+\begin{equation}
+ \begin{largearray}
+ \frac{\partial\Xi_{lN+j}(\mathbb U)}{\partial\mu}=
+ \partial_\mu\mathbb D^{(0)}(r_{l,j},e,\epsilon)
+ +
+ \sum_{l'}\sum_n\mathfrak F_{l',n}^{(\nu_u)}(\mathfrak u)\partial_\mu\mathbb D^{(1)}_{l',n}(r_{l,j},e,\epsilon)
+ +\\\hfill+
+ \sum_{l',l''}\sum_{n,m}\mathfrak F_{l',n}^{(\nu_u)}(\mathfrak u)\mathfrak F_{l'',m}^{(\nu_u)}(\mathfrak u)\partial_\mu\mathbb D^{(2)}_{l',n;l'',m}(r_{l,j},e,\epsilon)
+ \end{largearray}
+\end{equation}
+\begin{equation}
+ \begin{largearray}
+ \frac{\partial\Xi_{NJ+1}(\mathbb U)}{\partial \mu}
+ =\\\hfill=
+ 2\pi\rho
+ \frac
+ {
+ \partial_\mu C(\epsilon)
+ -
+ \partial_\mu\mathfrak g^{(0)}(e,\epsilon)
+ -
+ \sum_l\sum_n\mathfrak F_{l,n}^{(\nu_u)}(\mathfrak u)\partial_\mu\mathfrak g^{(1)}_{l,n}(e,\epsilon)
+ -
+ \sum_{l,l'}\sum_{n,m}\mathfrak F_{l,n}^{(\nu_u)}(\mathfrak u)\mathfrak F_{l',m}^{(\nu_u)}(\mathfrak u)\partial_\mu\mathfrak g^{(2)}_{l,n;l',m}(e,\epsilon)
+ }
+ {1-\frac83\pi\rho+\rho^2\left(
+ \bar{\mathfrak g}^{(0)}
+ +
+ \sum_l\sum_n\mathfrak F_{l,n}^{(\nu_u)}(\mathfrak u)\bar{\mathfrak g}^{(1)}_{l,n}
+ +
+ \sum_{l,l'}\sum_{n,m}\mathfrak F_{l,n}^{(\nu_u)}(\mathfrak u)\mathfrak F_{l',m}^{(\nu_u)}(\mathfrak u)\bar{\mathfrak g}^{(2)}_{l,n;l',m}
+ \right)}
+ .
+ \end{largearray}
+\end{equation}
+We then use $\partial_\mu=\frac1{4\sqrt\epsilon}\partial_{\sqrt\epsilon}$ and
+\begin{equation}
+ \left.\frac{\partial C(\epsilon)}{\partial\sqrt\epsilon}\right|_{\mu=0}
+ =
+ \frac83\sqrt\epsilon+2
+\end{equation}
+\begin{equation}
+ \begin{largearray}
+ \left.\frac{\partial D^{(0)}(r)}{\partial\sqrt\epsilon}\right|_{\mu=0}=
+ -\frac{2r}{r+1}e^{-2\sqrt{e}r}
+ \\[0.5cm]\hfill
+ +
+ \frac{\rho}{(r+1)}\int_0^{\min(1,r)} ds\ (s+1)B^{(0)}(s)e^{-2\sqrt{e}r}((-1-2\sqrt er)\sinh(2\sqrt{e} s)+2\sqrt es\cosh(2\sqrt{e} s))
+ \\[0.5cm]
+ +
+ \mathds 1_{r\leqslant 1}
+ \frac{\rho}{2(r+1)}\int_0^{1-r} d\sigma\ (\sigma+r+1)B^{(0)}(\sigma+r)
+ \cdot\\[0.5cm]\hfill\cdot
+ \left((-1-2\sqrt e\sigma)\left(1-e^{-4\sqrt er}\right)e^{-2\sqrt{e}\sigma}+4\sqrt ere^{-2\sqrt{e}(2r+\sigma)}\right)
+ \end{largearray}
+\end{equation}
+\begin{equation}
+ \begin{largearray}
+ \left.\frac{\partial D_{l,n}^{(1)}(r)}{\partial\sqrt\epsilon}\right|_{\mu=0}
+ =
+ \frac{\rho}{r+1}\int_0^{r} ds\ (s+1)B_{l,n}^{(1)}(s)e^{-2\sqrt er}\left(
+ (-1-2\sqrt er)\sinh(2\sqrt e s)
+ +2\sqrt es\cosh(2\sqrt e s)
+ \right)
+ \\[0.5cm]
+ +
+ \frac{\rho}{2(r+1)}\int_0^\infty d\sigma\ (\sigma+r+1)B_{l,n}^{(1)}(\sigma+r)
+ \cdot\\[0.5cm]\hfill\cdot
+ \left(
+ (-1-2\sqrt e\sigma)\left(1-e^{-4\sqrt er}\right)e^{-2\sqrt e\sigma}
+ +
+ 4\sqrt e re^{-2\sqrt e(2r+\sigma)}
+ \right)
+ \end{largearray}
+\end{equation}
+\begin{equation}
+ \begin{largearray}
+ \left.\frac{\partial D_{l,n;l',m}^{(2)}(r)}{\partial\sqrt\epsilon}\right|_{\mu=0}
+ \\[0.5cm]
+ =
+ \frac{\rho}{r+1}\int_0^{r} ds\ (s+1)B_{l,n;l',m}^{(2)}(s)e^{-2\sqrt er}\left(
+ (-1-2\sqrt er)\sinh(2\sqrt e s)
+ +2\sqrt es\cosh(2\sqrt e s)
+ \right)
+ \\[0.5cm]
+ +
+ \frac{\rho}{2(r+1)}\int_0^\infty d\sigma\ (\sigma+r+1)B_{l,n;l',m}^{(2)}(\sigma+r)
+ \cdot\\[0.5cm]\hfill\cdot
+ \left(
+ (-1-2\sqrt e\sigma)\left(1-e^{-4\sqrt er}\right)e^{-2\sqrt e\sigma}
+ +
+ 4\sqrt e re^{-2\sqrt e(2r+\sigma)}
+ \right)
+ .
+ \end{largearray}
+\end{equation}
+\begin{equation}
+ \left.\frac{\partial \gamma^{(0)}}{\partial\sqrt\epsilon}\right|_{\mu=0}
+ =
+ -4\rho e\int_0^1 d\sigma\ \sigma(\sigma+1)B^{(0)}(\sigma)e^{-2\sqrt e\sigma}
+\end{equation}
+\begin{equation}
+ \left.\frac{\partial\gamma^{(1)}_{l,n}}{\partial\sqrt\epsilon}\right|_{\mu=0}
+ =
+ -4\rho e\int_0^\infty d\sigma\ (\sigma+1)\sigma B_{l,n}^{(1)}(\sigma)e^{-2\sqrt e\sigma}
+\end{equation}
+and
+\begin{equation}
+ \left.\frac{\partial\gamma^{(2)}_{l,n;l',m}}{\partial\sqrt\epsilon}\right|_{\mu=0}
+ =
+ -4\rho e\int_0^\infty d\sigma\ (\sigma+1)\sigma B_{l,n;l',m}^{(2)}(\sigma)e^{-2\sqrt e\sigma}
+ .
+\end{equation}
+
+\subsection{\tt simpleq-iteration}\label{sec:simpleq-iteration}
+\indent
+This method is used to solve the Simple equation using the iteration described in\-~\cite{CJL20}.
+The Simple equation is
+\begin{equation}
+ -\Delta u
+ =
+ S-4e u+2e\rho u\ast u
+ \label{simpleq_iteration}
+\end{equation}
+\begin{equation}
+ S:=(1-u)v
+ ,\quad
+ \rho:=\frac{2e}{\int dx\ (1-u(|x|))v(|x|)}
+ .
+ \label{simpleq_Se}
+\end{equation}
+for a soft potential $v$ at fixed energy $e>0$.
+The iteration is defined as
+\begin{equation}
+ -\Delta u_n=S_n-4eu_n+2e\rho_{n-1}u_{n-1}\ast u_{n-1}
+ ,\quad
+ u_0=0
+ ,\quad
+ \rho_{n-1}=
+ \frac{2e}{\int dx\ (1-u_{n-1}(|x|))v(|x|)}
+ .
+ \label{iteration}
+\end{equation}
+\bigskip
+
+\subsubsection{Usage}
+\indent
+Unless otherwise noted, this method takes the following parameters (specified via the {\tt [-p params]} flag, as a `{\tt;}' separated list of entries).
+\begin{itemize}
+ \item\makelink{param:simpleq-iteration_e}{}
+ {\tt e} ({\tt Float64}, default: $10^{-4}$): energy $e$.
+
+ \item\makelink{param:simpleq-iteration_maxiter}{}
+ {\tt maxiter} ({\tt Int64}, default: 21): maximal number of iterations.
+
+ \item\makelink{param:simpleq-iteration_order}{}
+ {\tt order} ({\tt Int64}, default: 100): order used for all Gauss quadratures (denoted by $N$ below).
+
+\end{itemize}
+\bigskip
+
+The available {\tt commands} are the following.
+
+\begin{itemize}
+ \item {\tt rho\_e}\makelink{command:simpleq-iteration_rho_e}{}:
+ compute the density $\rho$ as a function of $e$.\par
+ \underline{Disabled parameters}: \refname{param:simpleq-iteration_e}{{\tt e}}.\par
+ \underline{Extra parameters}:
+ \begin{itemize}
+ \item\makelink{param:simpleq-iteration_minle}{}
+ {\tt minle} ({\tt Float64}, default: $10^{-6}$): minimal value for $\log_{10}e$.
+
+ \item\makelink{param:simpleq-iteration_maxle}{}
+ {\tt maxle} ({\tt Float64}, default: $10^{2}$): maximal value for $\log_{10}e$.
+
+ \item\makelink{param:simpleq-iteration_nle}{}
+ {\tt nle} ({\tt Int64}, default: $100$): number of values for $e$ (spaced logarithmically).
+
+ \item\makelink{param:simpleq-iteration_es}{}
+ {\tt es} ({\tt Array\{Float64\}}, default: $(10^{{\tt minle}+\frac{{\tt maxle}-{\tt minle}}{{\tt nle}}n})_n$: list of values for $e$, specified as a `{\tt,}' separated list.
+ \end{itemize}
+ \underline{Output} (one line for each value of $e$): [$e$] [$\rho$].
+
+ \item\makelink{command:simpleq-iteration_ux}{}
+ {\tt ux}: compute $u$ as a function of $|x|$.\par
+ \underline{Extra parameters}:
+ \begin{itemize}
+ \item\makelink{param:simpleq-iteration_xmin}{}
+ {\tt xmin} ({\tt Float64}, default: 0): minimum of the range of $|x|$ to be printed.
+
+ \item\makelink{param:simpleq-iteration_xmax}{}
+ {\tt xmax} ({\tt Float64}, default: 100): maximum of the range of $|x|$ to be printed.
+
+ \item\makelink{param:simpleq-iteration_nx}{}
+ {\tt nx} ({\tt Int64}, default: 100): number of points to print (linearly spaced).
+ \end{itemize}
+ \underline{Output} (one line for each value of $x$): [$|x|$] [$u_1(|x|)$] [$u_2(|x|)$] [$u_3(|x|)$] $\cdots$
+
+\end{itemize}
+
+\subsubsection{Description}
+\indent
+In Fourier space
+\begin{equation}
+ \hat u_n(|k|):=\int dx\ e^{ikx}u_n(|x|)
+\end{equation}
+(\ref{iteration}) becomes
+\begin{equation}
+ (k^2+4e)\hat u_n(|k|)=\hat S_n(|k|)+2e\rho_{n-1}\hat u_{n-1}(k)^2
+ ,\quad
+ \rho_n:=\frac{2e}{\hat S_n(0)}
+ \label{iteration_uk}
+\end{equation}
+with
+\begin{equation}
+ \hat S_n(|k|)
+ =\hat v(|k|)-\frac1{(2\pi)^3}\int dp\ \hat u_n(|p|)\hat v(|k-p|)
+ .
+\end{equation}
+We write $\hat S_n$ in bipolar coordinates (see lemma\-~\ref{lemma:bipolar}):
+\begin{equation}
+ \hat S_n(|k|)=\hat v(|k|)-\frac1{(2\pi)^3}\int_0^\infty dt\ t\hat u_n(t)\Eta(|k|,t)
+\end{equation}
+with
+\begin{equation}
+ \Eta(y,t):=\frac{2\pi}y\int_{|y-t|}^{y+t}ds\ s\hat v(s)
+\end{equation}
+(note that this agrees with the function\-~(\ref{easyeq_Eta}) defined for \refname{sec:easyeq}{{\tt easyeq}}).
+We also change variables to
+\begin{equation}
+ y=\frac1{t+1}
+ ,\quad
+ t=\frac{1-y}y
+\end{equation}
+\begin{equation}
+ \hat S_n(|k|)=\hat v(|k|)-\frac1{(2\pi)^3}\int_0^1 dy\ \frac{(1-y)\hat u_n(\frac{1-y}y)\Eta(|k|,\frac{1-y}y)}{y^3}
+ .
+\end{equation}
+We approximate this integral using a Gauss-Legendre quadrature (see appendix\-~\ref{appGL}) and discretize Fourier space:
+\begin{equation}
+ k_i:=\frac{1-x_i}{1+x_i}
+ ,\quad
+ y_i:=\frac{x_i+1}2
+\end{equation}
+where $x_i$ are the Gauss-Legendre abscissa, and
+\begin{equation}
+ \hat S_n(k_i)\approx\hat v(k_i)-\frac1{2(2\pi)^3}\sum_{j=1}^Nw_j\frac{(1-y_j)\hat u_n(\frac{1-y_j}{y_j})\Eta(k_i,\frac{1-y_j}{y_j})}{y_j^3}
+\end{equation}
+so if
+\begin{equation}
+ \mathbb U_i(n):=\hat u_n(k_i)
+ ,\quad
+ \mathbf v_i:=\hat v(k_i)
+\end{equation}
+we have
+\begin{equation}
+ \sum_{j=1}^NA_{i,j}\mathbb U_j(n)=b_i^{(n)}
+\end{equation}
+with
+\begin{equation}
+ A_{i,j}:=(k_i^2+4e)\delta_{i,j}+\frac{w_j(1-y_j)\Eta(k_i,\frac{1-y_j}{y_j})}{2(2\pi)^3y_j^3}
+\end{equation}
+and
+\begin{equation}
+ b_i^{(n)}:=\mathbf v_i+2e\rho_{n-1}\mathbb U_i(n-1)^2
+\end{equation}
+in terms of which
+\begin{equation}
+ \mathbb U=A^{-1}b^{(n)}
+ .
+\end{equation}
+Finally, we compute $\rho_n$ using the second of\-~(\ref{iteration_uk}):
+\begin{equation}
+ \rho_n=\frac{2e}{\hat S_n(0)}
+ ,\quad
+ S_n(0)\approx\hat v(0)
+ -\frac1{2(2\pi)^3}\sum_{j=1}^Nw_j\frac{(1-y_j)\hat u_n(\frac{1-y_j}{y_j})\Eta(0,\frac{1-y_j}{y_j})}{y_j^3}
+ .
+\end{equation}
+
+\section{Potentials}\label{sec:potentials}
+\indent
+In this section, we describe the potentials available in {\tt simplesolv}, and provide documentation to add custom potentials to {\tt simplesolv}.
+\bigskip
+
+\subsection{Built-in potentials}
+\subsubsection{{\tt exp}}\label{sec:exp}
+\indent
+In $x$-space,
+\begin{equation}
+ v(|x|)=ae^{-|x|}
+ .
+\end{equation}
+The constant $a$ is specified through the {\tt v\_a} parameter, and can be any real number.
+Note that $v\geqslant 0$ if and only if $a\geqslant 0$.
+This is the potential that is selected by default.
+\bigskip
+
+\point
+In Fourier space,
+\begin{equation}
+ \hat v(|k|)=\int dx\ e^{ikx}v(|x|)
+ =\frac{8\pi a}{(1+k^2)^2}
+ .
+\end{equation}
+In particular, $v$ is of positive type (that is, $\hat v\geqslant 0$) if and only if $a\geqslant 0$.
+\bigskip
+
+\point
+The zero energy scattering solution, that is, the solution of
+\begin{equation}
+ (-\Delta+v)\psi=0
+ ,\quad
+ \lim_{|x|\to\infty}\psi=1
+\end{equation}
+is
+\begin{equation}
+ \psi(r)=\frac{cI_0(2\sqrt a e^{-\frac r2})+2K_0(2\sqrt a e^{-\frac r2})}r
+ ,\quad
+ c=-\frac{2K_0(2\sqrt a)}{I_0(2\sqrt a)}
+\end{equation}
+where $I_0$ and $K_0$ are the modified Bessel functions, and the square root is taken with a branch cut on the negative imaginary axis.
+In other words, if $a<0$, $\sqrt a=i\sqrt{|a|}$ and\-~\dlmfcite{(10.27.6),(10.27.9),(10.27.10)}{1.1.3}
+\begin{equation}
+ I_0(ix)=J_0(x)
+ ,\quad
+ K_0(ix)=-\frac\pi2(Y_0(x)+iJ_0(x))
+\end{equation}
+where $J_0$ and $Y_0$ are the Bessel functions, so
+\begin{equation}
+ \psi(r)=\pi\frac{c'J_0(2\sqrt{|a|} e^{-\frac r2})-Y_0(2\sqrt{|a|} e^{-\frac r2})}r
+ ,\quad
+ c'=\frac{Y_0(2\sqrt{|a|})}{J_0(2\sqrt{|a|})}
+ .
+\end{equation}
+The scattering length is\-~\dlmfcite{(10.25.2),(10.31.2)}{1.1.3}
+\begin{equation}
+ \mathfrak a_0=\lim_{r\to\infty}r(1-\psi(r))
+ =\log(a)+2\gamma+\frac{2K_0(2\sqrt a)}{I_0(2\sqrt a)}
+\end{equation}
+where $\gamma$ is the Euler constant, which, for $a<0$, is
+\begin{equation}
+ \mathfrak a_0=\log|a|+2\gamma-\frac{\pi Y_0(2\sqrt{|a|})}{J_0(2\sqrt{|a|})}
+ .
+\end{equation}
+
+\subsubsection{{\tt tent}}\label{sec:tent}
+\indent
+In $x$-space,
+\begin{equation}
+ v(|x|)=\mathds 1_{|x|<b}a\frac{2\pi}3\left(1-\frac{|x|}b\right)^2\left(\frac{|x|}b+2\right)
+ .
+\end{equation}
+The constants $a$ and $b$ are specified through the {\tt v\_a} and {\tt v\_b} parameters, and $a\in\mathbb R$, $b>0$.
+Note that $v\geqslant 0$ if and only if $a\geqslant 0$.
+Note that
+\begin{equation}
+ v(|x|)=\frac a{b^3}\mathds 1_{|x|<\frac b2}\ast\mathds 1_{|x|<\frac b2}
+\end{equation}
+(this is more easily checked in Fourier space than explicitly computing the convolution).
+\bigskip
+
+\indent
+In Fourier space,
+\begin{equation}
+ \hat v(|k|)=\int dx\ e^{ikx}v(|x|)=a\frac{b^3}8\left(4\pi\frac{\sin(\frac{|k|b}2)-\frac{|k|b}2\cos(\frac{|k|b}2)}{\frac{(|k|b)^3}8}\right)^2
+ .
+\end{equation}
+Note that this is $\frac a{b^3}(\hat\mathds 1_{|x|<\frac b2})^2$.
+In particular, $v$ is of positive type (that is, $\hat v\geqslant 0$) if and only if $a\geqslant 0$.
+
+\subsubsection{{\tt expcry}}\label{sec:expcry}
+\indent
+In $x$-space
+\begin{equation}
+ v(|x|)=e^{-|x|}-ae^{-b|x|}
+ .
+\end{equation}
+The constants $a$ and $b$ are specified through the {\tt v\_a} and {\tt v\_b} parameters, and $a\in\mathbb R$, $b>0$.
+Note that $v\geqslant 0$ if and only if $a\leqslant 1$ and $b\geqslant 1$.
+\bigskip
+
+\indent
+In Fourier space
+\begin{equation}
+ \hat v(|k|)=\int dx\ e^{ikx}v(|x|)
+ =8\pi\left(\frac1{(1+k^2)^2}-\frac{ab}{(b^2+k^2)^2}\right)
+\end{equation}
+In particular, $\hat v$ is of positive type (that is, $\hat v\geqslant 0$) if and only if $ab\leqslant 1$, $a\leqslant b$ and $a\leqslant b^3$.
+If $a\leqslant 1$, $b\geqslant 1$ and $ab>1$, then $\hat v$ has a unique minimum at
+\begin{equation}
+ |k_*|=\sqrt{\frac{b^2-(ab)^{\frac13}}{(ab)^{\frac13}-1}}
+ ,\quad
+ \hat v(|k_*|)=
+ -8\pi\frac{((ab)^{\frac13}-1)^3}{b^2-1}
+ .
+\end{equation}
+
+\subsubsection{{\tt npt}}\label{sec:npt}
+\indent
+In $x$-space
+\begin{equation}
+ v(|x|)=x^2e^{-|x|}
+ .
+\end{equation}
+Note that $v\geqslant 0$.
+\bigskip
+
+\indent
+In Fourier space
+\begin{equation}
+ \hat v(|k|)=\int dx\ e^{ikx}v(|x|)
+ =96\pi\frac{1-k^2}{(1+k^2)^4}
+ .
+\end{equation}
+In particular, $v$ is not of positive type (that is, $\hat v$ is not $\geqslant 0$).
+
+\subsubsection{{\tt alg}}\label{sec:alg}
+\indent
+In $x$-space
+\begin{equation}
+ v(|x|)=\frac1{1+\frac14|x|^4}
+ .
+\end{equation}
+Note that $v\geqslant 0$.
+\bigskip
+
+\indent
+In Fourier space
+\begin{equation}
+ \hat v(|k|)=\int dx\ e^{ikx}v(|x|)
+ =4\pi^2 e^{-|k|}\frac{\sin(|k|)}{|k|}
+ .
+\end{equation}
+In particular, $v$ is not of positive type (that is, $\hat v$ is not $\geqslant 0$).
+
+\subsubsection{{\tt algwell}}\label{sec:algwell}
+\indent
+In $x$-space
+\begin{equation}
+ v(|x|)=\frac{1+a|x|^4}{(1+|x|^2)^4}
+ .
+\end{equation}
+The constant $a$ can be set using the parameter {\tt v\_a} and can be any real number.
+Note that $v\geqslant 0$ if and only if $a\geqslant 0$.
+If $a>8$, this potential has a local minimum at $|x_-|$ and a local maximum at $|x_+|$:
+\begin{equation}
+ |x_\pm|=\sqrt{\frac12(1\pm\sqrt{1-8a^{-1}})}
+ .
+\end{equation}
+\bigskip
+
+\indent
+In Fourier space
+\begin{equation}
+ \hat v(|k|)=\int dx\ e^{ikx}v(|x|)
+ =\frac{\pi^2}{24}e^{-|k|}(a(k^2-9|k|+15)+k^2+3|k|+3)
+ .
+\end{equation}
+In particular, $v$ is of positive type (that is, $\hat v$ is not $\geqslant 0$) if and only if
+\begin{equation}
+ -\frac15\leqslant a\leqslant 3+\frac87\sqrt7\approx6.02
+ .
+\end{equation}
+
+\subsubsection{{\tt exact}}\label{sec:exact}
+\indent
+In $x$-space
+\begin{equation}
+ v(|x|)=
+ \frac{12c( x^6b^6(2e-b^2) +b^4x^4(9e-7b^2) +4b^2x^2(3e-2b^2) +(5e+16b^2))}{(1+b^2x^2)^2(4+b^2x^2)^2((1+b^2x^2)^2-c)}
+\end{equation}
+The constants $a,b,c,e$ can be set using the parameters {\tt v\_a}, {\tt v\_b}, {\tt v\_c}, {\tt v\_e}, and $a,e\in\mathbb R$, $b\neq0$, $c>0$, $c\neq9$.
+Note that $v\geqslant 0$ if and only if\-~\cite{CJL20b}
+\begin{equation}
+ b>0
+ ,\quad
+ 0<c<1
+ ,\quad
+ \frac e{b^2}\geqslant\frac{-263+23\sqrt{161}}{48}\approx 0.601
+ .
+\end{equation}
+With this potential, the Simple equation has an exact solution:
+\begin{equation}
+ u=\frac c{(1+b^2x^2)^2}
+ ,\quad
+ \rho=\frac{b^3}{c\pi^2}
+ .
+\end{equation}
+\bigskip
+
+\indent
+In Fourier space $\hat v(|k|)=\int dx\ e^{ikx}v(x)$ is
+\begin{equation}
+ \begin{largearray}
+ \hat v(|k|)=\frac{48 c\pi^2}{|k|}
+ \left(
+ \frac{18+3\sqrt c-(4-3\alpha)c-(1-2\alpha)c^{\frac32}}{4(3+\sqrt c)^2c^{\frac32}}
+ e^{-\sqrt{1-\sqrt c}\frac{|k|}b}
+ \right.\\[0.5cm]\hfill\left.
+ +
+ \frac{-18+3\sqrt c+(4-3\alpha)c-(1-2\alpha)c^{\frac32}}{4(3-\sqrt c)^2c^{\frac32}}
+ e^{-\sqrt{1+\sqrt c}\frac{|k|}b}
+ +\frac{1-\frac{|k|}b}{2c}
+ e^{-\frac{|k|}b}
+ -\frac{\alpha(3(9-c)\frac{|k|}b+8c)}{8(9-c)^2}
+ e^{-2\frac{|k|}b}
+ \right)
+ \end{largearray}
+\end{equation}
+with $\alpha:=\frac e{b^2}$.
+
+\subsection{Programming custom potentials}
+\indent
+In this section, we provide documentation for programming custom potentials.
+\bigskip
+
+\indent
+The potentials are implemented in the file `{\tt \$SIMPLESOLV/src/potentials.jl}', and consist of two functions, one specifying the potential in Fourier space (the ``potential function''), and the other returning an approximate value for the scattering length (the ``scatterin glength function'') (as is explained below, a precise value of the scattering length is not actually needed).
+For instance, the potential \refname{sec:exp}{{\tt exp}} has two functions: {\tt v\_exp} and {\tt a0\_exp}.
+The potential function should take the following arguments:
+\begin{itemize}
+ \item {\tt k} ({\tt Float64}): the Fourier momentum
+ \item and any parameters that the potential depends on, such as $a$ in \refname{sec:exp}{{\tt exp}} (can be of any type, provided the appropriate changes are made to {\tt main.jl} as explained below)
+\end{itemize}
+and it must return a {\tt Float64}: the value of $\hat v$ at {\tt k}.
+The scattering length function takes the same parameters as an input, and returns a {\tt Float64}: the approximate value for the scattering length.
+\bigskip
+
+\indent
+In addition, the potential must be linked in `{\tt \$SIMPLESOLV/src/main.jl}'.
+In that file, the potential is read from the command line option {\tt U}.
+The relevant code is in lines 197-222.
+To add a new potential, add
+\begin{code}
+ elseif potential=="{\rm \{name of potential\}}"\par
+ \indent v=k->{\rm \{potential function\}}(k,v\_param\_a,v\_param\_b,{\rm...})\par
+ \indent a0={\rm \{scattering length function\}}(v\_param\_a,v\_param\_b,{\rm...})\par
+\end{code}
+where the number of {\tt v\_param} entries should be the number of parameters of the potential.
+The parameters that are currently read from the parameters list are {\tt a}, {\tt b}, {\tt c} and {\tt e}.
+To add a parameter, it must first be declared and initialized after line 35, and code to read it should be added after line 172:
+\begin{code}
+ elseif lhs="v\_{\rm\{name of parameter\}}"\par
+ \indent v\_param\_{\rm\{name of parameter\}}=parse(Float64,rhs)
+\end{code}
+If the new parameter has a type other than {\tt Float64}, this should be changed in the {\tt parse} function, and in the initialization.
+\bigskip
+
+\indent
+The approximation of the scattering length is only used to initialize the Newton algorithm for \refname{sec:easyeq}{{\tt easyeq}}, so it is not important that it be exact.
+In fact, some of the built-in potentials set the scattering length to 1, when it has proved too difficult to compute it exactly.
+
+\appendix
+
+\section{Chebyshev polynomial expansion}\label{appChebyshev}
+\indent
+In this appendix, we compute the error of Chebyshev polynomial expansions of regular functions.
+Specifically, we will consider class-$s$ Gevrey functions (which is a generalization of the notion of analyticity: analytic functions are Gevrey functions with $s=1$).
+A class-$s$ Gevrey function on $[-1,1]$ is a $\mathcal C^\infty$ function that satisfies, $\forall n\in\mathbb N$,
+\begin{equation}
+ \mathop{\mathrm{sup}}_{x\in[-1,1]}\left|\frac{d^nf(x)}{dx^n}\right|\leqslant C_0C^n(n!)^s.
+\end{equation}
+Formally, the Chebyshev polynomial expansion of $f$ is
+\begin{equation}
+ f(x)=\frac{c_0}2+\sum_{j=1}^\infty c_j T_j(x)
+ \label{eqcheby}
+\end{equation}
+where $T_j$ is the $j$-th Chebyshev polynomial:
+\begin{equation}
+ T_j(x):=\cos(j\arccos(x))
+\end{equation}
+and
+\begin{equation}
+ c_j:=\frac2\pi\int_0^\pi d\theta\ f(\cos\theta)\cos(j\theta)
+ .
+\end{equation}
+
+\bigskip
+
+\theo{Lemma}\label{lemmaChebyshev}
+ Let $f$ be a class-$s$ Gevrey function on $[-1,1]$ with $s\in\mathbb N\setminus\{0\}$.
+ There exist $b_0,b>0$, which are independent of $s$, such that the coefficients $c_j$ of the Chebyshev polynomial expansion are bounded as
+ \begin{equation}
+ c_j\leqslant b_0e^{-bj^{\frac1s}}
+ .
+ \label{boundchebyshevcoef}
+ \end{equation}
+ In particular, the Chebyshev polynomial expansion is absolutely convergent pointwise (and, therefore in any $L_p$ norm), and, for every $N\geqslant 1$,
+ \begin{equation}
+ \left|f(x)-\frac{c_0}2-\sum_{j=1}^N c_j T_j(x)\right|
+ \leqslant
+ \frac{b_0}{1-e^{-b}}(s-1)!(N^{\frac1s}+b^{-1})^{s-1}e^{-bN^{\frac1s}}
+ .
+ \label{boundchebyshev}
+ \end{equation}
+\endtheo
+\bigskip
+
+\indent\underline{Proof}:
+ Note that~\-(\ref{eqcheby}) is nothing other than the Fourier cosine series expansion of $F(\theta):=f(\cos(\theta))$, which is an even, periodic, class-$s$ Gevrey function on $[-\pi,\pi]$, whose $j$-th Fourier coefficient for $j\in\mathbb Z$ is equal to $\frac12c_{|j|}$.
+ The bound\-~(\ref{boundchebyshevcoef}) follows from a well-known estimate of the decay of Fourier coefficients of class-$s$ Gevrey functions (see e.g.~\-\cite[Theorem~\-3.3]{Ta87}).
+ The bound\-~(\ref{boundchebyshev}) then follows from $|T_j(x)|\leqslant 1$ and lemma\-~\ref{lemma:ineqgevrey} below.
+\qed
+\bigskip
+
+\theo{Lemma}\label{lemma:ineqgevrey}
+ Given $b>0$ and two integers $N,s>0$,
+ \nopagebreakaftereq
+ \begin{equation}
+ \sum_{j=N}^\infty e^{-bj^{\frac1s}}
+ \leqslant
+ (s-1)!\left(N^{\frac1s}+\frac1{1-e^{-b}}\right)^{s-1}\frac{e^{-bN^{\frac1s}}}{1-e^{-b}}
+ \end{equation}
+\endtheo
+\restorepagebreakaftereq
+\bigskip
+
+\indent\underline{Proof}:
+ If $\nu_{N,s}^s:=\lfloor N^{\frac1s}\rfloor^s$ denotes the largest integer that is $\leqslant N$ and has an integer $s$-th root, then
+ \begin{equation}
+ \sum_{j=N}^\infty e^{-bj^{\frac1s}}\leqslant
+ \sum_{j=\nu_{N,s}^s}^\infty e^{-bj^{\frac1s}}\leqslant
+ \sum_{k=\nu_{N,s}}^\infty(k^s-(k-1)^s)e^{-bk}\leqslant
+ s\sum_{k=\nu_{N,s}}^\infty k^{s-1}e^{-bk}
+ .
+ \end{equation}
+ We then estimate
+ \begin{equation}
+ \sum_{k=\nu_{N,s}}^\infty k^{s-1}e^{-bk}=\frac{d^{s-1}}{d(-b)^{s-1}}\sum_{k=\nu_{N,s}}^\infty e^{-bk}
+ \leqslant (s-1)!\left(\nu_{N,s}+\frac1{1-e^{-b}}\right)^{s-1}\frac{e^{-b\nu_{N,s}}}{1-e^{-b}}
+ \end{equation}
+ which concludes the proof of the lemma.
+\qed
+
+\section{Gauss quadratures}\label{appGL}
+\indent
+Gauss quadratures are approximation schemes to compute integrals of the form
+\begin{equation}
+ \int_a^bdt\ \omega(t)f(t)
+\end{equation}
+where $\omega(x)\geqslant 0$ is one of several functions that Gauss quadratures can treat.
+The possible choices of $\omega$ and $(a,b)$ are
+\begin{itemize}
+ \item $(a,b)=(-1,1)$, $\omega(t)=1$: Gauss-Legendre quadratures.
+ \item $(a,b)=(-1,1)$, $\omega(t)=(1-t)^\alpha(1+t)^\beta$, $\alpha,\beta>-1$: Gauss-Jacobi quadratures.
+ \item $(a,b)=(-1,1)$, $\omega(t)=(1-t^2)^{-\frac12}$: Gauss-Chebyshev quadratures.
+ \item $(a,b)=(0,\infty)$, $\omega(t)=e^{-t}$: Gauss-Laguerre quadratures.
+ \item $(a,b)=(0,\infty)$, $\omega(t)=t^\alpha e^{-t}$, $\alpha>-1$: generalized Gauss-Laguerre quadratures.
+ \item $(a,b)=(0,\infty)$, $\omega(t)=e^{-t^2}$: Gauss-Hermite quadratures.
+\end{itemize}
+It is not our goal here to discuss Gauss quadratures in detail, or their relation to orthogonal polynomials.
+Instead, we will compute the error made when approximating such an integral by a Gauss quadrature.
+\bigskip
+
+\indent
+For each Gauss quadrature, the integral is approximated in the form
+\begin{equation}
+ \int_a^b dt\ \omega(t) f(t)
+ \approx
+ \sum_{i=1}^Nw_if(r_i)
+\end{equation}
+where $w_i$ are called the {\it weights}, $r_i$ are the {\it abcissa}, and $N$ is the {\it order}.
+The weights and abcissa depend on both $\omega$ and the order $N$.
+The crucial property of Gauss quadratures is that they are {\it exact} when $f$ is a polynomial of order $\leqslant 2N-1$.
+\bigskip
+
+\indent
+In this appendix, we compute the error of Gauss quadratures when used to integrate regular functions.
+Specifically, we will consider class-$s$ Gevrey functions (which is a generalization of the notion of analyticity: analytic functions are Gevrey functions with $s=1$).
+A class-$s$ Gevrey function on is a $\mathcal C^\infty$ function that satisfies, $\forall n\in\mathbb N$,
+\begin{equation}
+ \mathop{\mathrm{sup}}_{x\in[-1,1]}\left|\frac{d^nf(x)}{dx^n}\right|\leqslant C_0C^n(n!)^s.
+\end{equation}
+
+\bigskip
+
+\theo{Lemma}\label{lemmaGL}
+ Let $f$ be a class-$s$ Gevrey function with $s\in\mathbb N\setminus\{0\}$.
+ There exist $b_0,b>0$, which are independent of $s$, and $N_0>0$, which is independent of $s$ and $f$, such that, if $N\geqslant N_0$, then, denoting the Gauss weights and abcissa by $w_i$ and $r_i$,
+ \begin{equation}
+ \left|\int_a^bdt\ \omega(t)f(t)-\sum_{i=1}^Nw_if(r_i)\right|
+ \leqslant
+ b_0(s-1)!((2N-1)^{\frac1s}+b^{-1})^{s-1}e^{-b(2N-1)^{\frac1s}}\left(\int_a^b\omega(t)+\sum_{i=1}^Nw_i\right)
+ .
+ \end{equation}
+ In particular, if $f$ is analytic (i.e. $s=1$), then
+ \begin{equation}
+ \left|\int_a^bdt\ \omega(t)f(t)-\sum_{i=1}^Nw_if(r_i)\right|
+ \leqslant b_0e^{-b(2N-1)}\left(\int_a^b\omega(t)+\sum_{i=1}^Nw_i\right)
+ .
+ \end{equation}
+\endtheo
+\bigskip
+
+\indent\underline{Proof}:
+ We expand $f$ into Chebyshev polynomials as in\-~(\ref{eqcheby}):
+ \begin{equation}
+ f(x)=\frac{c_0}2+\sum_{j=1}^{\infty}c_jT_j(x)
+ \end{equation}
+ Let
+ \begin{equation}
+ g(x):=f(x)-\frac{c_0}2-\sum_{j=1}^{2N-1} c_j T_j(x)
+ .
+ \end{equation}
+ Since order-$N$ Gauss quadratures are exact on polynomials of order $\leqslant 2N-1$, we have
+ \begin{equation}
+ \int_a^bdt\ \omega(t)f(t)-\sum_{i=1}^Nw_if(r_i)
+ =
+ \int_a^bdt\ \omega(t)g(t)-\sum_{i=1}^Nw_ig(r_i)
+ \end{equation}
+ and, by lemma\-~\ref{lemmaChebyshev},
+ \begin{equation}
+ |g(x)|\leqslant
+ (\mathrm{const}.)(s-1)!((2N-1)^{\frac1s}+b^{-1})^{s-1}e^{-b(2N-1)^{\frac1s}}
+ .
+ \label{boundchebyshev}
+ \end{equation}
+\qed
+
+\section{Bipolar coordinates}\label{appendix:bipolar}
+\indent
+Bipolar coordinates are very useful for computing convolutions of radial functions in three dimensions.
+\bigskip
+
+\theo{Lemma}\label{lemma:bipolar}
+ For $y\in\mathbb R^3$,
+ \nopagebreakaftereq
+ \begin{equation}
+ \int_{\mathbb R^3}dx\ f(|x|,|x-y|)
+ =
+ \frac{2\pi}{|y|}\int_0^\infty dt\int_{||y|-t|}^{|y|+t}ds\ stf(s,t)
+ \end{equation}
+\endtheo
+\restorepagebreakaftereq
+
+\indent\underline{Proof}:
+ Without loss of generality, we assume that $y=(0,0,a)$ with $a>0$. We first change to cylindrical coordinates: $(\rho,\theta,x_3)$:
+ \begin{equation}
+ \int_{\mathbb R^3}dx\ f(|x|,|x-y|)
+ =
+ 2\pi\int_0^\infty d\rho\int_{-\infty}^\infty dx_3\ \rho f(|(\rho,0,x_3)|,|(\rho,0,x_3-a)|)
+ .
+ \end{equation}
+ Next, we change variables to
+ \begin{equation}
+ s=|(\rho,0,x_3)|
+ ,\quad
+ t=|(\rho,0,x_3-a)|
+ .
+ \end{equation}
+ The inverse of this transformation is
+ \begin{equation}
+ x_3=\pm\frac{a^2+s^2-t^2}{2a}
+ ,\quad
+ \rho=\frac1{2a}\sqrt{4a^2s^2-(a^2+s^2-t^2)^2}
+ \label{inverse}
+ \end{equation}
+ and its Jacobian is
+ \begin{equation}
+ \frac{2ts}{\sqrt{-2a^4+2a^2(t^2+s^2)-(t^2-s^2)^2}}
+ =\frac{ts}{\rho a}
+ .
+ \label{jacobian}
+ \end{equation}
+\qed
+\bigskip
+
+\indent
+The following is a generalization of the previous lemma to functions of four variables.
+\bigskip
+
+\theo{Lemma}\label{lemma:bipolar2}
+ For $y\in\mathbb R^3$,
+ \begin{equation}
+ \begin{largearray}
+ \int_{\mathbb R^6}dxdx'\ f(|x|,|x-y|,|x'|,|x'-y|,|x-x'|)
+ \\[0.5cm]\hfill
+ =
+ \frac{2\pi}{|y|^2}\int_0^\infty dt\int_{||y|-t|}^{|y|+t}ds\int_0^\infty dt'\int_{||y|-t'|}^{|y|+t'}ds'\int_0^{2\pi}d\theta\ sts't'f(s,t,s',t',\xi(s,t,s',t',\theta,|y|))
+ \end{largearray}
+ \end{equation}
+ with
+ \nopagebreakaftereq
+ \begin{equation}
+ \begin{largearray}
+ \xi(s,t,s',t',\theta,|y|)
+ :=
+ \frac1{\sqrt 2|y|}
+ \Big(
+ |y|^2(s^2+t^2+(s')^2+(t')^2)-|y|^4-(s^2-t^2)((s')^2-(t')^2)
+ \\[0.5cm]\hfill
+ -
+ \sqrt{(4|y|^2s^2-(|y|^2+s^2-t^2)^2)(4|y|^2(s')^2-(|y|^2+(s')^2-(t')^2)^2)}\cos\theta
+ \Big)^{\frac12}
+ .
+ \end{largearray}
+ \end{equation}
+\endtheo
+\restorepagebreakaftereq
+
+\indent\underline{Proof}:
+ Without loss of generality, we assume that $y=(0,0,a)$ with $a>0$. We first change to cylindrical coordinates: $(\rho,\theta,x_3;\rho',\theta',x_3')$:
+ \begin{equation}
+ \begin{largearray}
+ \int_{\mathbb R^6}dxdx'\ f(|x|,|x-y|,|x'|,|x'-y|,|x-x'|)
+ \\[0.5cm]\hfill
+ =
+ 2\pi\int_0^\infty d\rho\int_{-\infty}^\infty dx_3
+ \int_0^\infty d\rho'\int_{-\infty}^\infty dx_3'\int_0^{2\pi}d\theta'
+ \ \rho\rho'
+ f(
+ s,t,s',t',
+ |(\rho-\rho'\cos\theta',\rho'\sin\theta',x_3-x_3')|
+ )
+ .
+ \end{largearray}
+ \end{equation}
+ where
+ \begin{equation}
+ s:=|(\rho,0,x_3)|
+ ,\quad
+ t:=|(\rho,0,x_3-a)|
+ ,\quad
+ s':=|(\rho'\cos\theta',\rho'\sin\theta',x_3')|,
+ t':=|(\rho'\cos\theta',\rho'\sin\theta',x_3'-a)|
+ \end{equation}
+ Next, we change variables to $(s,t,s',t',\theta')$.
+ The Jacobian of this transformation is, by\-~(\ref{jacobian}),
+ \begin{equation}
+ \frac{tst's'}{\rho\rho' a^2}
+ .
+ \end{equation}
+ Furthermore, by\-~(\ref{inverse}),
+ \begin{equation}
+ x_3-x_3'=\frac{s^2-t^2-(s')^2+(t')^2}{2a}
+ \end{equation}
+ and
+ \begin{equation}
+ \rho=\frac{\sqrt{4a^2s^2-(a^2+s^2-t^2)^2}}{2a}
+ ,\quad
+ \rho'=\frac{\sqrt{4a^2(s')^2-(a^2+(s')^2-(t')^2)^2}}{2a}
+ \end{equation}
+ so
+ \begin{equation}
+ \begin{largearray}
+ |(\rho-\rho'\cos\theta',\rho'\sin\theta',x_3-x_3')|
+ =
+ \frac1{2a}
+ \left(
+ 4a^2s^2-(a^2+s^2-t^2)^2
+ +
+ 4a^2(s')^2-(a^2+(s')^2-(t')^2)^2
+ \right.\\[0.5cm]\hfill\left.
+ -
+ 2\sqrt{(4a^2s^2-(a^2+s^2-t^2)^2)(4a^2(s')^2-(a^2+(s')^2-(t')^2)^2)}\cos\theta'
+ +
+ (s^2-t^2-(s')^2+(t')^2)^2
+ \right)^{\frac12}
+ \end{largearray}
+ \end{equation}
+ and
+ \begin{equation}
+ \begin{largearray}
+ |(\rho-\rho'\cos\theta',\rho'\sin\theta',x_3-x_3')|
+ =
+ \frac1{\sqrt 2a}
+ \Big(
+ a^2(s^2+t^2+(s')^2+(t')^2)-a^4-(s^2-t^2)((s')^2-(t')^2)
+ \\[0.5cm]\hfill
+ -
+ \sqrt{(4a^2s^2-(a^2+s^2-t^2)^2)(4a^2(s')^2-(a^2+(s')^2-(t')^2)^2)}\cos\theta'
+ \Big)^{\frac12}
+ .
+ \end{largearray}
+ \end{equation}
+\qed
+
+\section{Hann windowing}\label{appendix:hann}
+\indent
+In this appendix, we discuss the use of Hann windows to compute Fourier transforms.
+Consider the Fourier transform
+\begin{equation}
+ \hat f(k)=\int dx\ e^{ikx}f(x)
+ .
+\end{equation}
+Evaluating this integral numerically can be tricky, especially at high $|k|$, because of the rapid oscillations at large $|x|$.
+A trick to palliate such a problem is to multiply $f$ by a {\it window function} $h_L$, which cuts off distances of order $L$.
+We then compute, instead of $\hat f$,
+\begin{equation}
+ \tilde f(k)=\int dx\ e^{ikx}h_L(x)f(x)
+ .
+\end{equation}
+We can then evaluate $\tilde f$ using standard numerical techniques, such as Gauss quadratures (see appendix\-~\ref{appGL}), without issues at large $|x|$.
+However, in doing so, we will make an error in the Fourier transform.
+To quantify this error, note that
+\begin{equation}
+ \tilde f(k)
+ =\hat h_L\hat\ast\hat f(k)
+ \equiv\int\frac{dq}{(2\pi)^d}\ \hat h_L(q)\hat f(k-q)
+\end{equation}
+so if we choose $h_L$ in such a way that $\hat h_L$ is peaked around the origin, then $\tilde f$ will not differ too much from $\hat f$:
+\begin{equation}
+ \hat f(k)-\tilde f(k)
+ =((2\pi)^d\delta(k)-\hat h_L)\hat\ast\hat f(k)
+ .
+\end{equation}
+\bigskip
+
+\indent
+The {\it Hann} window is defined as
+\begin{equation}
+ h_L(x)=\cos^2({\textstyle\frac{\pi|x|}L})\mathds 1_{|x|<\frac L2}
+\end{equation}
+whose Fourier transform is, in $d=3$,
+\begin{equation}
+ \hat h_L(k)=
+ \frac{4\pi^3 L^2}{|k|}\frac{((|k|L)^3-4|k|L\pi^2)\cos(\frac{|k|L}2)-2(3(|k|L)^2-4\pi^2)\sin(\frac{|k|L}2)}{((|k|L)^3-4|k|L\pi^2)^2}
+\end{equation}
+which decays at large $|k|L$ as
+\begin{equation}
+ \hat h_L(k)\sim\frac{4\pi^3}{|k|^4L}\cos({\textstyle\frac{|k|L}2})
+ .
+\end{equation}
+
+
+
+\vfill
+\eject
+
+\begin{thebibliography}{WWW99}
+\small
+\IfFileExists{bibliography/bibliography.tex}{\input bibliography/bibliography.tex}{}
+\end{thebibliography}
+
+
+\end{document}
diff --git a/src/anyeq.jl b/src/anyeq.jl
new file mode 100644
index 0000000..8459cb0
--- /dev/null
+++ b/src/anyeq.jl
@@ -0,0 +1,949 @@
+## Copyright 2021 Ian Jauslin
+##
+## 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.
+
+# interpolation
+@everywhere mutable struct Anyeq_approx
+ aK::Float64
+ bK::Float64
+ gK::Float64
+ aL1::Float64
+ bL1::Float64
+ aL2::Float64
+ bL2::Float64
+ gL2::Float64
+ aL3::Float64
+ bL3::Float64
+ gL3::Float64
+end
+
+# compute energy for a given rho
+# use minlrho, nlrho to incrementally compute the solution to medeq (to initialize the Newton algorithm)
+function anyeq_energy(rho,minlrho,nlrho,taus,P,N,J,a0,v,maxiter,tolerance,approx,savefile)
+ # initialize vectors
+ (weights,T,k,V,V0,A,Upsilon,Upsilon0)=anyeq_init(taus,P,N,J,v)
+ # init Abar
+ if savefile!=""
+ Abar=anyeq_read_Abar(savefile,P,N,J)
+ else
+ Abar=anyeq_Abar_multithread(k,weights,taus,T,P,N,J,approx)
+ end
+
+ # compute initial guess from medeq
+ rhos=Array{Float64}(undef,nlrho)
+ for j in 0:nlrho-1
+ rhos[j+1]=(nlrho==1 ? rho : 10^(minlrho+(log10(rho)-minlrho)/(nlrho-1)*j))
+ end
+ u0s=anyeq_init_medeq(rhos,N,J,k,a0,v,maxiter,tolerance)
+ u0=u0s[nlrho]
+
+ (u,E,error)=anyeq_hatu(u0,P,N,J,rho,a0,weights,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,v,maxiter,tolerance,approx)
+
+ @printf("% .15e % .15e\n",E,error)
+end
+
+# compute energy as a function of rho
+function anyeq_energy_rho(rhos,taus,P,N,J,a0,v,maxiter,tolerance,approx,savefile)
+ # initialize vectors
+ (weights,T,k,V,V0,A,Upsilon,Upsilon0)=anyeq_init(taus,P,N,J,v)
+
+ # init Abar
+ if savefile!=""
+ Abar=anyeq_read_Abar(savefile,P,N,J)
+ else
+ Abar=anyeq_Abar_multithread(k,weights,taus,T,P,N,J,approx)
+ end
+
+ # compute initial guess from medeq
+ u0s=anyeq_init_medeq(rhos,N,J,k,a0,v,maxiter,tolerance)
+
+ # save result from each task
+ es=Array{Float64,1}(undef,length(rhos))
+ err=Array{Float64,1}(undef,length(rhos))
+
+ ## spawn workers
+ # number of workers
+ nw=nworkers()
+ # split jobs among workers
+ work=Array{Array{Int64,1},1}(undef,nw)
+ # init empty arrays
+ for p in 1:nw
+ work[p]=zeros(0)
+ end
+ for j in 1:length(rhos)
+ append!(work[(j-1)%nw+1],j)
+ end
+
+ count=0
+ # for each worker
+ @sync for p in 1:nw
+ # for each task
+ @async for j in work[p]
+ count=count+1
+ if count>=nw
+ progress(count,length(rhos),10000)
+ end
+ # run the task
+ (u,es[j],err[j])=remotecall_fetch(anyeq_hatu,workers()[p],u0s[j],P,N,J,rhos[j],a0,weights,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,v,maxiter,tolerance,approx)
+ end
+ end
+
+ for j in 1:length(rhos)
+ @printf("% .15e % .15e % .15e\n",rhos[j],es[j],err[j])
+ end
+end
+
+# compute energy as a function of rho
+# initialize with previous rho
+function anyeq_energy_rho_init_prevrho(rhos,taus,P,N,J,a0,v,maxiter,tolerance,approx,savefile)
+ # initialize vectors
+ (weights,T,k,V,V0,A,Upsilon,Upsilon0)=anyeq_init(taus,P,N,J,v)
+
+ # init Abar
+ if savefile!=""
+ Abar=anyeq_read_Abar(savefile,P,N,J)
+ else
+ Abar=anyeq_Abar_multithread(k,weights,taus,T,P,N,J,approx)
+ end
+
+ # compute initial guess from medeq
+ u0s=anyeq_init_medeq([rhos[1]],N,J,k,a0,v,maxiter,tolerance)
+ u=u0s[1]
+
+ for j in 1:length(rhos)
+ progress(j,length(rhos),10000)
+ # run the task
+ # init Newton from previous rho
+ (u,E,error)=anyeq_hatu(u,P,N,J,rhos[j],a0,weights,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,v,maxiter,tolerance,approx)
+ @printf("% .15e % .15e % .15e\n",rhos[j],E,error)
+ # abort when the error gets too big
+ if error>tolerance
+ break
+ end
+ end
+end
+# compute energy as a function of rho
+# initialize with next rho
+function anyeq_energy_rho_init_nextrho(rhos,taus,P,N,J,a0,v,maxiter,tolerance,approx,savefile)
+ # initialize vectors
+ (weights,T,k,V,V0,A,Upsilon,Upsilon0)=anyeq_init(taus,P,N,J,v)
+
+ # init Abar
+ if savefile!=""
+ Abar=anyeq_read_Abar(savefile,P,N,J)
+ else
+ Abar=anyeq_Abar_multithread(k,weights,taus,T,P,N,J,approx)
+ end
+
+ # compute initial guess from medeq
+ u0s=anyeq_init_medeq([rhos[length(rhos)]],N,J,k,a0,v,maxiter,tolerance)
+ u=u0s[1]
+
+ for j in 1:length(rhos)
+ progress(j,length(rhos),10000)
+ # run the task
+ # init Newton from previous rho
+ (u,E,error)=anyeq_hatu(u,P,N,J,rhos[length(rhos)+1-j],a0,weights,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,v,maxiter,tolerance,approx)
+ @printf("% .15e % .15e % .15e\n",rhos[length(rhos)+1-j],real(E),error)
+ # abort when the error gets too big
+ if error>tolerance
+ break
+ end
+ end
+end
+
+# compute u(k)
+# use minlrho, nlrho to incrementally compute the solution to medeq (to initialize the Newton algorithm)
+function anyeq_uk(minlrho,nlrho,taus,P,N,J,rho,a0,v,maxiter,tolerance,approx,savefile)
+ # init vectors
+ (weights,T,k,V,V0,A,Upsilon,Upsilon0)=anyeq_init(taus,P,N,J,v)
+ # init Abar
+ if savefile!=""
+ Abar=anyeq_read_Abar(savefile,P,N,J)
+ else
+ Abar=anyeq_Abar_multithread(k,weights,taus,T,P,N,J,approx)
+ end
+ # compute initial guess from medeq
+ rhos=Array{Float64}(undef,nlrho)
+ for j in 0:nlrho-1
+ rhos[j+1]=(nlrho==1 ? rho : 10^(minlrho+(log10(rho)-minlrho)/(nlrho-1)*j))
+ end
+ u0s=anyeq_init_medeq(rhos,N,J,k,a0,v,maxiter,tolerance)
+ u0=u0s[nlrho]
+
+ (u,E,error)=anyeq_hatu(u0,P,N,J,rho,a0,weights,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,v,maxiter,tolerance,approx)
+
+ for zeta in 0:J-1
+ for j in 1:N
+ # order k's in increasing order
+ @printf("% .15e % .15e\n",k[(J-1-zeta)*N+j],u[(J-1-zeta)*N+j])
+ end
+ end
+end
+
+# compute u(x)
+# use minlrho, nlrho to incrementally compute the solution to medeq (to initialize the Newton algorithm)
+function anyeq_ux(minlrho,nlrho,taus,P,N,J,rho,a0,v,maxiter,tolerance,xmin,xmax,nx,approx,savefile)
+ # init vectors
+ (weights,T,k,V,V0,A,Upsilon,Upsilon0)=anyeq_init(taus,P,N,J,v)
+ # init Abar
+ if savefile!=""
+ Abar=anyeq_read_Abar(savefile,P,N,J)
+ else
+ Abar=anyeq_Abar_multithread(k,weights,taus,T,P,N,J,approx)
+ end
+
+ # compute initial guess from medeq
+ rhos=Array{Float64}(undef,nlrho)
+ for j in 0:nlrho-1
+ rhos[j+1]=(nlrho==1 ? rho : 10^(minlrho+(log10(rho)-minlrho)/(nlrho-1)*j))
+ end
+ u0s=anyeq_init_medeq(rhos,N,J,k,a0,v,maxiter,tolerance)
+ u0=u0s[nlrho]
+
+ (u,E,error)=anyeq_hatu(u0,P,N,J,rho,a0,weights,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,v,maxiter,tolerance,approx)
+
+ for i in 1:nx
+ x=xmin+(xmax-xmin)*i/nx
+ ux=0.
+ for zeta in 0:J-1
+ for j in 1:N
+ ux+=(taus[zeta+2]-taus[zeta+1])/(16*pi*x)*weights[2][j]*cos(pi*weights[1][j]/2)*(1+k[zeta*N+j])^2*k[zeta*N+j]*u[zeta*N+j]*sin(k[zeta*N+j]*x)
+ end
+ end
+ @printf("% .15e % .15e % .15e\n",x,real(ux),imag(ux))
+ end
+end
+
+# compute condensate fraction for a given rho
+# use minlrho, nlrho to incrementally compute the solution to medeq (to initialize the Newton algorithm)
+function anyeq_condensate_fraction(rho,minlrho,nlrho,taus,P,N,J,a0,v,maxiter,tolerance,approx,savefile)
+ # initialize vectors
+ (weights,T,k,V,V0,A,Upsilon,Upsilon0)=anyeq_init(taus,P,N,J,v)
+ # init Abar
+ if savefile!=""
+ Abar=anyeq_read_Abar(savefile,P,N,J)
+ else
+ Abar=anyeq_Abar_multithread(k,weights,taus,T,P,N,J,approx)
+ end
+
+ # compute initial guess from medeq
+ rhos=Array{Float64}(undef,nlrho)
+ for j in 0:nlrho-1
+ rhos[j+1]=(nlrho==1 ? rho : 10^(minlrho+(log10(rho)-minlrho)/(nlrho-1)*j))
+ end
+ u0s=anyeq_init_medeq(rhos,N,J,k,a0,v,maxiter,tolerance)
+ u0=u0s[nlrho]
+
+ (u,E,error)=anyeq_hatu(u0,P,N,J,rho,a0,weights,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,v,maxiter,tolerance,approx)
+
+ # compute eta
+ eta=anyeq_eta(u,P,N,J,rho,weights,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,approx)
+
+ @printf("% .15e % .15e\n",eta,error)
+end
+
+# condensate fraction as a function of rho
+function anyeq_condensate_fraction_rho(rhos,taus,P,N,J,a0,v,maxiter,tolerance,approx,savefile)
+ ## spawn workers
+ # number of workers
+ nw=nworkers()
+ # split jobs among workers
+ work=Array{Array{Int64,1},1}(undef,nw)
+ # init empty arrays
+ for p in 1:nw
+ work[p]=zeros(0)
+ end
+ for j in 1:length(rhos)
+ append!(work[(j-1)%nw+1],j)
+ end
+
+ # initialize vectors
+ (weights,T,k,V,V0,A,Upsilon,Upsilon0)=anyeq_init(taus,P,N,J,v)
+ # init Abar
+ if savefile!=""
+ Abar=anyeq_read_Abar(savefile,P,N,J)
+ else
+ Abar=anyeq_Abar_multithread(k,weights,taus,T,P,N,J,approx)
+ end
+
+ # compute initial guess from medeq
+ u0s=anyeq_init_medeq(rhos,N,J,k,a0,v,maxiter,tolerance)
+
+ # compute u
+ us=Array{Array{Float64,1}}(undef,length(rhos))
+ errs=Array{Float64,1}(undef,length(rhos))
+ count=0
+ # for each worker
+ @sync for p in 1:nw
+ # for each task
+ @async for j in work[p]
+ count=count+1
+ if count>=nw
+ progress(count,length(rhos),10000)
+ end
+ # run the task
+ (us[j],E,errs[j])=remotecall_fetch(anyeq_hatu,workers()[p],u0s[j],P,N,J,rhos[j],a0,weights,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,v,maxiter,tolerance,approx)
+ end
+ end
+
+ # compute eta
+ etas=Array{Float64}(undef,length(rhos))
+ count=0
+ # for each worker
+ @sync for p in 1:nw
+ # for each task
+ @async for j in work[p]
+ count=count+1
+ if count>=nw
+ progress(count,length(rhos),10000)
+ end
+ # run the task
+ etas[j]=anyeq_eta(us[j],P,N,J,rhos[j],weights,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,approx)
+ end
+ end
+
+ for j in 1:length(rhos)
+ @printf("% .15e % .15e % .15e\n",rhos[j],etas[j],errs[j])
+ end
+end
+
+# compute the momentum distribution for a given rho
+# use minlrho, nlrho to incrementally compute the solution to medeq (to initialize the Newton algorithm)
+function anyeq_momentum_distribution(rho,minlrho,nlrho,taus,P,N,J,a0,v,maxiter,tolerance,approx,savefile)
+ # initialize vectors
+ (weights,T,k,V,V0,A,Upsilon,Upsilon0)=anyeq_init(taus,P,N,J,v)
+ # init Abar
+ if savefile!=""
+ Abar=anyeq_read_Abar(savefile,P,N,J)
+ else
+ Abar=anyeq_Abar_multithread(k,weights,taus,T,P,N,J,approx)
+ end
+
+ # compute initial guess from medeq
+ rhos=Array{Float64}(undef,nlrho)
+ for j in 0:nlrho-1
+ rhos[j+1]=(nlrho==1 ? rho : 10^(minlrho+(log10(rho)-minlrho)/(nlrho-1)*j))
+ end
+ u0s=anyeq_init_medeq(rhos,N,J,k,a0,v,maxiter,tolerance)
+ u0=u0s[nlrho]
+
+ (u,E,error)=anyeq_hatu(u0,P,N,J,rho,a0,weights,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,v,maxiter,tolerance,approx)
+
+ # compute M
+ M=anyeq_momentum(u,P,N,J,rho,weights,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,approx)
+
+ for zeta in 0:J-1
+ for j in 1:N
+ # order k's in increasing order
+ @printf("% .15e % .15e\n",k[(J-1-zeta)*N+j],M[(J-1-zeta)*N+j])
+ end
+ end
+end
+
+# 2 point correlation function
+function anyeq_2pt_correlation(minlrho,nlrho,taus,P,N,J,windowL,rho,a0,v,maxiter,tolerance,xmin,xmax,nx,approx,savefile)
+ # init vectors
+ (weights,T,k,V,V0,A,Upsilon,Upsilon0)=anyeq_init(taus,P,N,J,v)
+ # init Abar
+ if savefile!=""
+ Abar=anyeq_read_Abar(savefile,P,N,J)
+ else
+ Abar=anyeq_Abar_multithread(k,weights,taus,T,P,N,J,approx)
+ end
+
+ # compute initial guess from medeq
+ rhos=Array{Float64}(undef,nlrho)
+ for j in 0:nlrho-1
+ rhos[j+1]=(nlrho==1 ? rho : 10^(minlrho+(log10(rho)-minlrho)/(nlrho-1)*j))
+ end
+ u0s=anyeq_init_medeq(rhos,N,J,k,a0,v,maxiter,tolerance)
+ u0=u0s[nlrho]
+
+ # compute u and some useful integrals
+ (u,E,error)=anyeq_hatu(u0,P,N,J,rho,a0,weights,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,v,maxiter,tolerance,approx)
+ (S,E,II,JJ,X,Y,sL1,sK,G)=anyeq_SEIJGXY(rho*u,rho,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,weights,P,N,J,approx)
+
+ for i in 1:nx
+ x=xmin+(xmax-xmin)*i/nx
+ C2=anyeq_2pt(x,u,P,N,J,windowL,rho,weights,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,approx,S,E,II,JJ,X,Y,sL1,sK,G)
+ @printf("% .15e % .15e\n",x,C2)
+ end
+end
+
+# compute Abar
+function anyeq_Abar_multithread(k,weights,taus,T,P,N,J,approx)
+ if approx.bL3==0.
+ return []
+ end
+
+ out=Array{Array{Float64,5}}(undef,J*N)
+
+ ## spawn workers
+ # number of workers
+ nw=nworkers()
+ # split jobs among workers
+ work=Array{Array{Int64,1},1}(undef,nw)
+ # init empty arrays
+ for p in 1:nw
+ work[p]=zeros(0)
+ end
+ for j in 1:N*J
+ append!(work[(j-1)%nw+1],j)
+ end
+
+ count=0
+ # for each worker
+ @sync for p in 1:nw
+ # for each task
+ @async for j in work[p]
+ count=count+1
+ if count>=nw
+ progress(count,N*J,10000)
+ end
+ # run the task
+ out[j]=remotecall_fetch(barAmat,workers()[p],k[j],weights,taus,T,P,N,J,2,2,2,2,2)
+ end
+ end
+
+ return out
+end
+
+# initialize computation
+@everywhere function anyeq_init(taus,P,N,J,v)
+ # Gauss-Legendre weights
+ weights=gausslegendre(N)
+
+ # initialize vectors V,k
+ V=Array{Float64}(undef,J*N)
+ k=Array{Float64}(undef,J*N)
+ for zeta in 0:J-1
+ for j in 1:N
+ xj=weights[1][j]
+ # set kj
+ k[zeta*N+j]=(2+(taus[zeta+2]-taus[zeta+1])*sin(pi*xj/2)-(taus[zeta+2]+taus[zeta+1]))/(2-(taus[zeta+2]-taus[zeta+1])*sin(pi*xj/2)+taus[zeta+2]+taus[zeta+1])
+ # set v
+ V[zeta*N+j]=v(k[zeta*N+j])
+ end
+ end
+ # potential at 0
+ V0=v(0)
+
+ # initialize matrix A
+ T=chebyshev_polynomials(P)
+ A=Amat(k,weights,taus,T,P,N,J,2,2)
+
+ # compute Upsilon
+ # Upsilonmat does not use splines, so increase precision
+ weights_plus=gausslegendre(N*J)
+ Upsilon=Upsilonmat(k,v,weights_plus)
+ Upsilon0=Upsilon0mat(k,v,weights_plus)
+
+ return(weights,T,k,V,V0,A,Upsilon,Upsilon0)
+end
+
+# compute initial guess from medeq
+@everywhere function anyeq_init_medeq(rhos,N,J,k,a0,v,maxiter,tolerance)
+ us_medeq=Array{Array{Float64,1}}(undef,length(rhos))
+ u0s=Array{Array{Float64,1}}(undef,length(rhos))
+
+ weights_medeq=gausslegendre(N*J)
+
+ (us_medeq[1],E,err)=easyeq_hatu(easyeq_init_u(a0,J*N,weights_medeq),J*N,rhos[1],v,maxiter,tolerance,weights_medeq,Easyeq_approx(1.,1.))
+ u0s[1]=easyeq_to_anyeq(us_medeq[1],weights_medeq,k,N,J)
+ if err>tolerance
+ print(stderr,"warning: computation of initial Ansatz failed for rho=",rhos[1],"\n")
+ end
+
+ for j in 2:length(rhos)
+ (us_medeq[j],E,err)=easyeq_hatu(us_medeq[j-1],J*N,rhos[j],v,maxiter,tolerance,weights_medeq,Easyeq_approx(1.,1.))
+ u0s[j]=easyeq_to_anyeq(us_medeq[j],weights_medeq,k,N,J)
+
+ if err>tolerance
+ print(stderr,"warning: computation of initial Ansatz failed for rho=",rhos[j],"\n")
+ end
+ end
+
+ return u0s
+end
+
+# interpolate the solution of medeq to an input for anyeq
+@everywhere function easyeq_to_anyeq(u_simple,weights,k,N,J)
+ # reorder u_simple, which is evaluated at (1-x_j)/(1+x_j) with x_j\in[-1,1]
+ u_s=zeros(Float64,length(u_simple))
+ k_s=Array{Float64}(undef,length(u_simple))
+ for j in 1:length(u_simple)
+ xj=weights[1][j]
+ k_s[length(u_simple)-j+1]=(1-xj)/(1+xj)
+ u_s[length(u_simple)-j+1]=u_simple[j]
+ end
+
+ # initialize U
+ u=zeros(Float64,J*N)
+ for zeta in 0:J-1
+ for j in 1:N
+ u[zeta*N+j]=linear_interpolation(k[zeta*N+j],k_s,u_s)
+ end
+ end
+
+ return u
+end
+
+
+# compute u using chebyshev expansions
+@everywhere function anyeq_hatu(u0,P,N,J,rho,a0,weights,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,v,maxiter,tolerance,approx)
+ # init
+ # rescale by rho (that's how u is defined)
+ u=rho*u0
+
+ # quantify relative error
+ error=-1.
+
+ # run Newton algorithm
+ for i in 1:maxiter-1
+ (S,E,II,JJ,X,Y,sL1,sK,G)=anyeq_SEIJGXY(u,rho,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,weights,P,N,J,approx)
+ new=u-inv(anyeq_DXi(u,rho,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,weights,P,N,J,approx,S,E,II,JJ,X,Y,sL1,sK))*anyeq_Xi(u,X,Y)
+
+ error=norm(new-u)/norm(u)
+ if(error<tolerance)
+ u=new
+ break
+ end
+
+ u=new
+ end
+
+ energy=rho/2*V0-avg_v_chebyshev(u,Upsilon0,k,taus,weights,N,J)/2
+ return(u/rho,energy,error)
+end
+
+
+# save Abar
+function anyeq_save_Abar(taus,P,N,J,v,approx)
+ # initialize vectors
+ (weights,T,k,V,V0,A,Upsilon,Upsilon0)=anyeq_init(taus,P,N,J,v)
+
+ # init Abar
+ Abar=anyeq_Abar_multithread(k,weights,taus,T,P,N,J,approx)
+
+ # print params
+ @printf("## P=%d N=%d J=%d\n",P,N,J)
+
+ for i in 1:N*J
+ for j1 in 1:(P+1)*J
+ for j2 in 1:(P+1)*J
+ for j3 in 1:(P+1)*J
+ for j4 in 1:(P+1)*J
+ for j5 in 1:(P+1)*J
+ @printf("% .15e\n",Abar[i][j1,j2,j3,j4,j5])
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+# read Abar
+function anyeq_read_Abar(savefile,P,N,J)
+ # open file
+ ff=open(savefile,"r")
+ # read all lines
+ lines=readlines(ff)
+ close(ff)
+
+ # init
+ Abar=Array{Array{Float64,5}}(undef,N*J)
+ for i in 1:N*J
+ Abar[i]=Array{Float64,5}(undef,(P+1)*J,(P+1)*J,(P+1)*J,(P+1)*J,(P+1)*J)
+ end
+
+ i=1
+ j1=1
+ j2=1
+ j3=1
+ j4=1
+ j5=0
+ for l in 1:length(lines)
+ # drop comments
+ if lines[l]!="" && lines[l][1]!='#'
+ # increment counters
+ if j5<(P+1)*J
+ j5+=1
+ else
+ j5=1
+ if j4<(P+1)*J
+ j4+=1
+ else
+ j4=1
+ if j3<(P+1)*J
+ j3+=1
+ else
+ j3=1
+ if j2<(P+1)*J
+ j2+=1
+ else
+ j2=1
+ if j1<(P+1)*J
+ j1+=1
+ else
+ j1=1
+ if i<N*J
+ i+=1
+ else
+ print(stderr,"error: too many lines in savefile\n")
+ exit()
+ end
+ end
+ end
+ end
+ end
+ end
+
+ Abar[i][j1,j2,j3,j4,j5]=parse(Float64,lines[l])
+
+ end
+ end
+
+ return Abar
+
+end
+
+
+
+# Xi
+# takes the vector of kj's and xn's as input
+@everywhere function anyeq_Xi(U,X,Y)
+ return U-(Y.+1)./(2*(X.+1)).*dotPhi((Y.+1)./((X.+1).^2))
+end
+
+# DXi
+# takes the vector of kj's as input
+@everywhere function anyeq_DXi(U,rho,k,taus,v,v0,A,Abar,Upsilon,Upsilon0,weights,P,N,J,approx,S,E,II,JJ,X,Y,sL1,sK)
+ out=Array{Float64,2}(undef,N*J,N*J)
+ for zetapp in 0:J-1
+ for n in 1:N
+ one=zeros(Int64,J*N)
+ one[zetapp*N+n]=1
+
+ # Chebyshev expansion of U
+ FU=chebyshev(U,taus,weights,P,N,J,2)
+
+ dS=-conv_one_v_chebyshev(n,zetapp,Upsilon,k,taus,weights,N,J)/rho
+
+ dE=-avg_one_v_chebyshev(n,zetapp,Upsilon0,k,taus,weights,N)/rho
+
+ UU=conv_chebyshev(FU,FU,A)
+
+ dII=zeros(Float64,N*J)
+ if approx.gL2!=0.
+ if approx.bL2!=0.
+ dII+=approx.gL2*approx.bL2*(conv_one_chebyshev(n,zetapp,chebyshev(U.*S,taus,weights,P,N,J,2),A,taus,weights,P,N,J,2)/rho+conv_chebyshev(FU,chebyshev(one.*S+U.*dS,taus,weights,P,N,J,2),A)/rho)
+ end
+ if approx.bL2!=1.
+ dII+=approx.gL2*(1-approx.bL2)*(dE/rho*UU+2*E/rho*conv_one_chebyshev(n,zetapp,FU,A,taus,weights,P,N,J,2))
+ end
+ end
+
+ dJJ=zeros(Float64,J*N)
+ if approx.gL3!=0.
+ if approx.bL3!=0.
+ FS=chebyshev(S,taus,weights,P,N,J,2)
+ dFU=chebyshev(one,taus,weights,P,N,J,2)
+ dFS=chebyshev(dS,taus,weights,P,N,J,2)
+ dJJ+=approx.gL3*approx.bL3*(4*double_conv_S_chebyshev(FU,FU,FU,dFU,FS,Abar)+double_conv_S_chebyshev(FU,FU,FU,FU,dFS,Abar))
+ end
+ if approx.bL3!=1.
+ dJJ+=approx.gL3*(1-approx.bL3)*(dE*(UU/rho).^2+4*E*conv_one_chebyshev(n,zetapp,FU,A,taus,weights,P,N,J,2).*UU/rho^2)
+ end
+ end
+
+ dG=zeros(Float64,N*J)
+ if approx.aK!=0. && approx.gK!=0.
+ if approx.bK!=0.
+ dG+=approx.aK*approx.gK*approx.bK*(conv_one_chebyshev(n,zetapp,chebyshev(2*S.*U,taus,weights,P,N,J,2),A,taus,weights,P,N,J,2)/rho+conv_chebyshev(FU,chebyshev(2*S.*one+2*dS.*U,taus,weights,P,N,J,2),A)/rho)
+ end
+ if approx.bK!=1.
+ dG+=approx.aK*approx.gK*(1-approx.bK)*(2*dE*UU/rho+4*E*conv_one_chebyshev(n,zetapp,FU,A,taus,weights,P,N,J,2)/rho)
+ end
+ end
+ if approx.aL1!=0.
+ if approx.bL1!=0.
+ dG-=approx.aL1*approx.bL1*(conv_one_chebyshev(n,zetapp,chebyshev(S.*(U.^2),taus,weights,P,N,J,2),A,taus,weights,P,N,J,2)/rho+conv_chebyshev(FU,chebyshev(2*S.*U.*one+dS.*(U.^2),taus,weights,P,N,J,2),A)/rho)
+ end
+ if approx.bL1!=1.
+ dG-=approx.aL1*(1-approx.bL1)*(E/rho*conv_one_chebyshev(n,zetapp,chebyshev((U.^2),taus,weights,P,N,J,2),taus,A,weights,P,N,J,2)+conv_chebyshev(FU,chebyshev(2*E*U.*one+dE*(U.^2),taus,weights,P,N,J,2),A)/rho)
+ end
+ end
+ if approx.aL2!=0. && approx.gL2!=0.
+ dG+=approx.aL2*(conv_one_chebyshev(n,zetapp,chebyshev(2*II.*U,taus,weights,P,N,J,2),A,taus,weights,P,N,J,2)/rho+conv_chebyshev(FU,chebyshev(2*dII.*U+2*II.*one,taus,weights,P,N,J,2),A)/rho)
+ end
+ if approx.aL3!=0. && approx.gL3!=0.
+ dG-=approx.aL3*(conv_one_chebyshev(n,zetapp,chebyshev(JJ/2,taus,weights,P,N,J,2),A,taus,weights,P,N,J,2)/rho+conv_chebyshev(FU,chebyshev(dJJ/2,taus,weights,P,N,J,2),A)/rho)
+ end
+
+ dsK=zeros(Float64,N*J)
+ if approx.gK!=0.
+ if approx.bK!=0.
+ dsK+=approx.gK*approx.bK*dS
+ end
+ if approx.bK!=1.
+ dsK+=approx.gK*(1-approx.bK)*dE*ones(N*J)
+ end
+ else
+ end
+ dsL1=zeros(Float64,N*J)
+ if approx.bL1!=0.
+ dsL1+=approx.bL1*dS
+ end
+ if approx.bL1!=1.
+ dsL1+=(1-approx.bL1)*dE*ones(Float64,N*J)
+ end
+
+ dX=(dsK-dsL1+dII)./sL1-X./sL1.*dsL1
+ dY=(dS-dsL1+dG+dJJ/2)./sL1-Y./sL1.*dsL1
+
+ out[:,zetapp*N+n]=one+((Y.+1).*dX./(X.+1)-dY)./(2*(X.+1)).*dotPhi((Y.+1)./((X.+1).^2))+(Y.+1)./(2*(X.+1).^3).*(2*(Y.+1)./(X.+1).*dX-dY).*dotdPhi((Y.+1)./(X.+1).^2)
+ end
+ end
+ return out
+end
+
+# compute S,E,I,J,X and Y
+@everywhere function anyeq_SEIJGXY(U,rho,k,taus,v,v0,A,Abar,Upsilon,Upsilon0,weights,P,N,J,approx)
+ # Chebyshev expansion of U
+ FU=chebyshev(U,taus,weights,P,N,J,2)
+
+ S=v-conv_v_chebyshev(U,Upsilon,k,taus,weights,N,J)/rho
+ E=v0-avg_v_chebyshev(U,Upsilon0,k,taus,weights,N,J)/rho
+
+ UU=conv_chebyshev(FU,FU,A)
+
+ II=zeros(Float64,N*J)
+ if approx.gL2!=0.
+ if approx.bL2!=0.
+ II+=approx.gL2*approx.bL2*conv_chebyshev(FU,chebyshev(U.*S,taus,weights,P,N,J,2),A)/rho
+ end
+ if approx.bL2!=1.
+ II+=approx.gL2*(1-approx,bL2)*E/rho*UU
+ end
+ end
+
+ JJ=zeros(Float64,N*J)
+ if approx.gL3!=0.
+ if approx.bL3!=0.
+ FS=chebyshev(S,taus,weights,P,N,J,2)
+ JJ+=approx.gL3*approx.bL3*double_conv_S_chebyshev(FU,FU,FU,FU,FS,Abar)
+ end
+ if approx.bL3!=1.
+ JJ+=approx.gL3*(1-approx.bL3)*E*(UU/rho).^2
+ end
+ end
+
+ G=zeros(Float64,N*J)
+ if approx.aK!=0. && approx.gK!=0.
+ if approx.bK!=0.
+ G+=approx.aK*approx.gK*approx.bK*conv_chebyshev(FU,chebyshev(2*S.*U,taus,weights,P,N,J,2),A)/rho
+ end
+ if approx.bK!=1.
+ G+=approx.aK*approx.gK*(1-approx.bK)*2*E*UU/rho
+ end
+ end
+ if approx.aL1!=0.
+ if approx.bL1!=0.
+ G-=approx.aL1*approx.bL1*conv_chebyshev(FU,chebyshev(S.*(U.^2),taus,weights,P,N,J,2),A)/rho
+ end
+ if approx.bL1!=1.
+ G-=approx.aL1*(1-approx.bL1)*E/rho*conv_chebyshev(FU,chebyshev((U.^2),taus,weights,P,N,J,2),A)
+ end
+ end
+ if approx.aL2!=0. && approx.gL2!=0.
+ G+=approx.aL2*conv_chebyshev(FU,chebyshev(2*II.*U,taus,weights,P,N,J,2),A)/rho
+ end
+ if approx.aL3!=0 && approx.gL3!=0.
+ G-=approx.aL3*conv_chebyshev(FU,chebyshev(JJ/2,taus,weights,P,N,J,2),A)/rho
+ end
+
+ sK=zeros(Float64,N*J)
+ if approx.gK!=0.
+ if approx.bK!=0.
+ sK+=approx.gK*approx.bK*S
+ end
+ if approx.bK!=1.
+ sK+=approx.gK*(1-approx.bK)*E*ones(Float64,N*J)
+ end
+ end
+
+ sL1=zeros(Float64,N*J)
+ if approx.bL1!=0.
+ sL1+=approx.bL1*S
+ end
+ if approx.bL1!=1.
+ sL1+=(1-approx.bL1)*E*ones(Float64,N*J)
+ end
+
+ X=(k.^2/2+rho*(sK-sL1+II))./sL1/rho
+ Y=(S-sL1+G+JJ/2)./sL1
+
+ return(S,E,II,JJ,X,Y,sL1,sK,G)
+end
+
+# condensate fraction
+@everywhere function anyeq_eta(u,P,N,J,rho,weights,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,approx)
+ # compute dXi/dmu
+ (S,E,II,JJ,X,Y,sL1,sK,G)=anyeq_SEIJGXY(rho*u,rho,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,weights,P,N,J,approx)
+ dXidmu=(Y.+1)./(rho*sL1)./(2*(X.+1).^2).*dotPhi((Y.+1)./((X.+1).^2))+(Y.+1).^2 ./((X.+1).^4)./(rho*sL1).*dotdPhi((Y.+1)./(X.+1).^2)
+
+ # compute eta
+ du=-inv(anyeq_DXi(rho*u,rho,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,weights,P,N,J,approx,S,E,II,JJ,X,Y,sL1,sK))*dXidmu
+ eta=-avg_v_chebyshev(du,Upsilon0,k,taus,weights,N,J)/2
+
+ return eta
+end
+
+# momentum distribution
+@everywhere function anyeq_momentum(u,P,N,J,rho,weights,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,approx)
+ # compute dXi/dlambda (without delta functions)
+ (S,E,II,JJ,X,Y,sL1,sK,G)=anyeq_SEIJGXY(rho*u,rho,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,weights,P,N,J,approx)
+ dXidlambda=-(2*pi)^3*2*u./sL1.*(dotPhi((Y.+1)./((X.+1).^2))./(2*(X.+1))+(Y.+1)./(2*(X.+1).^3).*dotdPhi((Y.+1)./(X.+1).^2))
+
+ # approximation for delta function (without Kronecker deltas)
+ delta=Array{Float64}(undef,J*N)
+ for zeta in 0:J-1
+ for n in 1:N
+ delta[zeta*N+n]=2/pi^2/((taus[zeta+2]-taus[zeta+1])*weights[2][n]*cos(pi*weights[1][n]/2)*(1+k[zeta*N+n])^2*k[zeta*N+n]^2)
+ end
+ end
+
+ # compute dXidu
+ dXidu=inv(anyeq_DXi(rho*u,rho,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,weights,P,N,J,approx,S,E,II,JJ,X,Y,sL1,sK))
+
+ M=Array{Float64}(undef,J*N)
+ for i in 1:J*N
+ # du/dlambda
+ du=dXidu[:,i]*dXidlambda[i]*delta[i]
+
+ # compute M
+ M[i]=-avg_v_chebyshev(du,Upsilon0,k,taus,weights,N,J)/2
+ end
+
+ return M
+end
+
+
+# correlation function
+@everywhere function anyeq_2pt(x,u,P,N,J,windowL,rho,weights,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,approx,S,E,II,JJ,X,Y,sL1,sK,G)
+ # initialize dV
+ dV=Array{Float64}(undef,J*N)
+ for i in 1:J*N
+ if x>0
+ dV[i]=sin(k[i]*x)/(k[i]*x)*hann(k[i],windowL)
+ else
+ dV[i]=hann(k[i],windowL)
+ end
+ end
+ dV0=1.
+
+ # compute dUpsilon
+ # Upsilonmat does not use splines, so increase precision
+ weights_plus=gausslegendre(N*J)
+ dUpsilon=Upsilonmat(k,r->sin(r*x)/(r*x)*hann(r,windowL),weights_plus)
+ dUpsilon0=Upsilon0mat(k,r->sin(r*x)/(r*x)*hann(r,windowL),weights_plus)
+
+ du=-inv(anyeq_DXi(rho*u,rho,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,weights,P,N,J,approx,S,E,II,JJ,X,Y,sL1,sK))*anyeq_dXidv(x,rho*u,rho,k,taus,dV,dV0,A,Abar,dUpsilon,dUpsilon0,weights,P,N,J,approx,S,E,II,JJ,X,Y,sL1,sK)
+ # rescale rho
+ du=du/rho
+
+ C2=rho^2*(1-integrate_f_chebyshev(s->1.,u.*dV+V.*du,k,taus,weights,N,J))
+
+ return C2
+end
+
+# derivative of Xi with respect to v in the direction sin(kx)/kx
+@everywhere function anyeq_dXidv(x,U,rho,k,taus,dv,dv0,A,Abar,dUpsilon,dUpsilon0,weights,P,N,J,approx,S,E,II,JJ,X,Y,sL1,sK)
+ # Chebyshev expansion of U
+ FU=chebyshev(U,taus,weights,P,N,J,2)
+
+ dS=dv-conv_v_chebyshev(U,dUpsilon,k,taus,weights,N,J)/rho
+ dE=dv0-avg_v_chebyshev(U,dUpsilon0,k,taus,weights,N,J)/rho
+
+ UU=conv_chebyshev(FU,FU,A)
+
+ dII=zeros(Float64,N*J)
+ if approx.gL2!=0.
+ if approx.bL2!=0.
+ dII+=approx.gL2*approx.bL2*conv_chebyshev(FU,chebyshev(U.*dS,taus,weights,P,N,J,2),A)/rho
+ end
+ if approx.bL2!=1.
+ dII+=approx.gL2*(1-approx,bL2)*dE/rho*UU
+ end
+ end
+
+ dJJ=zeros(Float64,J*N)
+ if approx.gL3!=0.
+ if approx.bL3!=0.
+ dFS=chebyshev(dS,taus,weights,P,N,J,2)
+ dJJ+=approx.gL3*approx.bL3*double_conv_S_chebyshev(FU,FU,FU,FU,dFS,Abar)
+ end
+ if approx.bL3!=1.
+ dJJ=approx.gL3*(1-approx.bL3)*dE*(UU/rho).^2
+ end
+ end
+
+ dG=zeros(Float64,N*J)
+ if approx.aK!=0. && approx.gK!=0.
+ if approx.bK!=0.
+ dG+=approx.aK*approx.gK*approx.bK*conv_chebyshev(FU,chebyshev(2*dS.*U,taus,weights,P,N,J,2),A)/rho
+ end
+ if approx.bK!=1.
+ dG+=approx.aK*approx.gK*(1-approx.bK)*2*dE*UU/rho
+ end
+ end
+ if approx.aL1!=0.
+ if approx.bL1!=0.
+ dG-=approx.aL1*approx.bL1*conv_chebyshev(FU,chebyshev(dS.*(U.^2),taus,weights,P,N,J,2),A)/rho
+ end
+ if approx.bL1!=1.
+ dG-=approx.aL1*(1-approx.bL1)*dE/rho*conv_chebyshev(FU,chebyshev((U.^2),taus,weights,P,N,J,2),A)
+ end
+ end
+ if approx.aL2!=0. && approx.gL2!=0.
+ dG+=approx.aL2*conv_chebyshev(FU,chebyshev(2*dII.*U,taus,weights,P,N,J,2),A)/rho
+ end
+ if approx.aL3!=0. && approx.gL3!=0.
+ dG-=approx.aL3*conv_chebyshev(FU,chebyshev(dJJ/2,taus,weights,P,N,J,2),A)/rho
+ end
+
+ dsK=zeros(Float64,N*J)
+ if approx.gK!=0.
+ if approx.bK!=0.
+ dsK+=approx.gK*approx.bK*dS
+ end
+ if approx.bK!=1.
+ dsK+=approx.gK*(1-approx.bK)*dE*ones(N*J)
+ end
+ end
+ dsL1=zeros(Float64,N*J)
+ if approx.bL1!=0.
+ dsL1+=approx.bL1*dS
+ end
+ if approx.bL1!=1.
+ dsL1+=(1-approx.bL1)*dE*ones(N*J)
+ end
+
+ dX=(dsK-dsL1+dII)./sL1-X./sL1.*dsL1
+ dY=(dS-dsL1+dG+dJJ/2)./sL1-Y./sL1.*dsL1
+
+ out=((Y.+1).*dX./(X.+1)-dY)./(2*(X.+1)).*dotPhi((Y.+1)./((X.+1).^2))+(Y.+1)./(2*(X.+1).^3).*(2*(Y.+1)./(X.+1).*dX-dY).*dotdPhi((Y.+1)./(X.+1).^2)
+ return out
+end
diff --git a/src/chebyshev.jl b/src/chebyshev.jl
new file mode 100644
index 0000000..28c8f1f
--- /dev/null
+++ b/src/chebyshev.jl
@@ -0,0 +1,279 @@
+## Copyright 2021 Ian Jauslin
+##
+## 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.
+
+# Chebyshev expansion
+@everywhere function chebyshev(a,taus,weights,P,N,J,nu)
+ out=zeros(Float64,J*(P+1))
+ for zeta in 0:J-1
+ for n in 0:P
+ for j in 1:N
+ out[zeta*(P+1)+n+1]+=(2-(n==0 ? 1 : 0))/2*weights[2][j]*cos(n*pi*(1+weights[1][j])/2)*a[zeta*N+j]/(1-(taus[zeta+2]-taus[zeta+1])/2*sin(pi*weights[1][j]/2)+(taus[zeta+2]+taus[zeta+1])/2)^nu
+ end
+ end
+ end
+
+ return out
+end
+
+# evaluate function from Chebyshev expansion
+@everywhere function chebyshev_eval(Fa,x,taus,chebyshev,P,J,nu)
+ # change variable
+ tau=(1-x)/(1+x)
+
+ out=0.
+ for zeta in 0:J-1
+ # check that the spline is right
+ if tau<taus[zeta+2] && tau>=taus[zeta+1]
+ for n in 0:P
+ out+=Fa[zeta*(P+1)+n+1]*chebyshev[n+1]((2*tau-(taus[zeta+1]+taus[zeta+2]))/(taus[zeta+2]-taus[zeta+1]))
+ end
+ break
+ end
+ end
+
+ return (1+tau)^nu*out
+end
+
+
+# convolution
+# input the Chebyshev expansion of a and b, as well as the A matrix
+@everywhere function conv_chebyshev(Fa,Fb,A)
+ out=zeros(Float64,length(A))
+ for i in 1:length(A)
+ out[i]=dot(Fa,A[i]*Fb)
+ end
+ return out
+end
+
+# <ab>
+@everywhere function avg_chebyshev(Fa,Fb,A0)
+ return dot(Fa,A0*Fb)
+end
+
+# 1_n * a
+@everywhere function conv_one_chebyshev(n,zetapp,Fa,A,taus,weights,P,N,J,nu1)
+ out=zeros(Float64,N*J)
+ for m in 1:N*J
+ for l in 0:P
+ for p in 1:J*(P+1)
+ out[m]+=(2-(l==0 ? 1 : 0))/2*weights[2][n]*cos(l*pi*(1+weights[1][n])/2)/(1-(taus[zetapp+2]-taus[zetapp+1])/2*sin(pi*weights[1][n]/2)+(taus[zetapp+2]+taus[zetapp+1])/2)^nu1*A[m][zetapp*(P+1)+l+1,p]*Fa[p]
+ end
+ end
+ end
+ return out
+end
+# a * v
+@everywhere function conv_v_chebyshev(a,Upsilon,k,taus,weights,N,J)
+ out=zeros(Float64,J*N)
+ for i in 1:J*N
+ for zetap in 0:J-1
+ for j in 1:N
+ xj=weights[1][j]
+ out[i]+=(taus[zetap+2]-taus[zetap+1])/(32*pi)*weights[2][j]*cos(pi*xj/2)*(1+k[zetap*N+j])^2*k[zetap*N+j]*a[zetap*N+j]*Upsilon[zetap*N+j][i]
+ end
+ end
+ end
+ return out
+end
+@everywhere function conv_one_v_chebyshev(n,zetap,Upsilon,k,taus,weights,N,J)
+ out=zeros(Float64,J*N)
+ xj=weights[1][n]
+ for i in 1:J*N
+ out[i]=(taus[zetap+2]-taus[zetap+1])/(32*pi)*weights[2][n]*cos(pi*xj/2)*(1+k[zetap*N+n])^2*k[zetap*N+n]*Upsilon[zetap*N+n][i]
+ end
+ return out
+end
+
+# <av>
+@everywhere function avg_v_chebyshev(a,Upsilon0,k,taus,weights,N,J)
+ out=0.
+ for zetap in 0:J-1
+ for j in 1:N
+ xj=weights[1][j]
+ out+=(taus[zetap+2]-taus[zetap+1])/(32*pi)*weights[2][j]*cos(pi*xj/2)*(1+k[zetap*N+j])^2*k[zetap*N+j]*a[zetap*N+j]*Upsilon0[zetap*N+j]
+ end
+ end
+ return out
+end
+# <1_nv>
+@everywhere function avg_one_v_chebyshev(n,zetap,Upsilon0,k,taus,weights,N)
+ xj=weights[1][n]
+ return (taus[zetap+2]-taus[zetap+1])/(32*pi)*weights[2][n]*cos(pi*xj/2)*(1+k[zetap*N+n])^2*k[zetap*N+n]*Upsilon0[zetap*N+n]
+end
+
+# compute \int dq dxi u1(k-xi)u2(q)u3(xi)u4(k-q)u5(xi-q)
+@everywhere function double_conv_S_chebyshev(FU1,FU2,FU3,FU4,FU5,Abar)
+ out=zeros(Float64,length(Abar))
+ for i in 1:length(Abar)
+ for j1 in 1:length(FU1)
+ for j2 in 1:length(FU2)
+ for j3 in 1:length(FU3)
+ for j4 in 1:length(FU4)
+ for j5 in 1:length(FU5)
+ out[i]+=Abar[i][j1,j2,j3,j4,j5]*FU1[j1]*FU2[j2]*FU3[j3]*FU4[j4]*FU5[j5]
+ end
+ end
+ end
+ end
+ end
+ end
+ return out
+end
+
+
+# compute A
+@everywhere function Amat(k,weights,taus,T,P,N,J,nua,nub)
+ out=Array{Array{Float64,2},1}(undef,J*N)
+ for i in 1:J*N
+ out[i]=zeros(Float64,J*(P+1),J*(P+1))
+ for zeta in 0:J-1
+ for n in 0:P
+ for zetap in 0:J-1
+ for m in 0:P
+ out[i][zeta*(P+1)+n+1,zetap*(P+1)+m+1]=1/(pi^2*k[i])*integrate_legendre(tau->(1-tau)/(1+tau)^(3-nua)*T[n+1]((2*tau-(taus[zeta+1]+taus[zeta+2]))/(taus[zeta+2]-taus[zeta+1]))*(alpham(k[i],tau)>taus[zetap+2] || alphap(k[i],tau)<taus[zetap+1] ? 0. : integrate_legendre(sigma->(1-sigma)/(1+sigma)^(3-nub)*T[m+1]((2*sigma-(taus[zetap+1]+taus[zetap+2]))/(taus[zetap+2]-taus[zetap+1])),max(taus[zetap+1],alpham(k[i],tau)),min(taus[zetap+2],alphap(k[i],tau)),weights)),taus[zeta+1],taus[zeta+2],weights)
+ end
+ end
+ end
+ end
+ end
+
+ return out
+end
+
+# compute Upsilon
+@everywhere function Upsilonmat(k,v,weights)
+ out=Array{Array{Float64,1},1}(undef,length(k))
+ for i in 1:length(k)
+ out[i]=Array{Float64,1}(undef,length(k))
+ for j in 1:length(k)
+ out[i][j]=integrate_legendre(s->s*v(s)/k[j],abs(k[j]-k[i]),k[j]+k[i],weights)
+ end
+ end
+ return out
+end
+@everywhere function Upsilon0mat(k,v,weights)
+ out=Array{Float64,1}(undef,length(k))
+ for j in 1:length(k)
+ out[j]=2*k[j]*v(k[j])
+ end
+ return out
+end
+
+# alpha_-
+@everywhere function alpham(k,t)
+ return (1-k-(1-t)/(1+t))/(1+k+(1-t)/(1+t))
+end
+# alpha_+
+@everywhere function alphap(k,t)
+ return (1-abs(k-(1-t)/(1+t)))/(1+abs(k-(1-t)/(1+t)))
+end
+
+
+# compute \bar A
+@everywhere function barAmat(k,weights,taus,T,P,N,J,nu1,nu2,nu3,nu4,nu5)
+ out=zeros(Float64,J*(P+1),J*(P+1),J*(P+1),J*(P+1),J*(P+1))
+ for zeta1 in 0:J-1
+ for n1 in 0:P
+ for zeta2 in 0:J-1
+ for n2 in 0:P
+ for zeta3 in 0:J-1
+ for n3 in 0:P
+ for zeta4 in 0:J-1
+ for n4 in 0:P
+ for zeta5 in 0:J-1
+ for n5 in 0:P
+ out[zeta1*(P+1)+n1+1,
+ zeta2*(P+1)+n2+1,
+ zeta3*(P+1)+n3+1,
+ zeta4*(P+1)+n4+1,
+ zeta5*(P+1)+n5+1]=1/((2*pi)^5*k^2)*integrate_legendre(tau->barAmat_int1(tau,k,taus,T,weights,nu1,nu2,nu3,nu4,nu5,zeta1,zeta2,zeta3,zeta4,zeta5,n1,n2,n3,n4,n5),taus[zeta1+1],taus[zeta1+2],weights)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+ return out
+end
+@everywhere function barAmat_int1(tau,k,taus,T,weights,nu1,nu2,nu3,nu4,nu5,zeta1,zeta2,zeta3,zeta4,zeta5,n1,n2,n3,n4,n5)
+ if(alpham(k,tau)<taus[zeta2+2] && alphap(k,tau)>taus[zeta2+1])
+ return 2*(1-tau)/(1+tau)^(3-nu1)*T[n1+1]((2*tau-(taus[zeta1+1]+taus[zeta1+2]))/(taus[zeta1+2]-taus[zeta1+1]))*integrate_legendre(sigma->barAmat_int2(tau,sigma,k,taus,T,weights,nu2,nu3,nu4,nu5,zeta2,zeta3,zeta4,zeta5,n2,n3,n4,n5),max(taus[zeta2+1],alpham(k,tau)),min(taus[zeta2+2],alphap(k,tau)),weights)
+ else
+ return 0.
+ end
+end
+@everywhere function barAmat_int2(tau,sigma,k,taus,T,weights,nu2,nu3,nu4,nu5,zeta2,zeta3,zeta4,zeta5,n2,n3,n4,n5)
+ return 2*(1-sigma)/(1+sigma)^(3-nu2)*T[n2+1]((2*sigma-(taus[zeta2+1]+taus[zeta2+2]))/(taus[zeta2+2]-taus[zeta2+1]))*integrate_legendre(taup->barAmat_int3(tau,sigma,taup,k,taus,T,weights,nu3,nu4,nu5,zeta3,zeta4,zeta5,n3,n4,n5),taus[zeta3+1],taus[zeta3+2],weights)
+end
+@everywhere function barAmat_int3(tau,sigma,taup,k,taus,T,weights,nu3,nu4,nu5,zeta3,zeta4,zeta5,n3,n4,n5)
+ if(alpham(k,taup)<taus[zeta4+2] && alphap(k,taup)>taus[zeta4+1])
+ return 2*(1-taup)/(1+taup)^(3-nu3)*T[n3+1]((2*taup-(taus[zeta3+1]+taus[zeta3+2]))/(taus[zeta3+2]-taus[zeta3+1]))*integrate_legendre(sigmap->barAmat_int4(tau,sigma,taup,sigmap,k,taus,T,weights,nu4,nu5,zeta4,zeta5,n4,n5),max(taus[zeta4+1],alpham(k,taup)),min(taus[zeta4+2],alphap(k,taup)),weights)
+ else
+ return 0.
+ end
+end
+@everywhere function barAmat_int4(tau,sigma,taup,sigmap,k,taus,T,weights,nu4,nu5,zeta4,zeta5,n4,n5)
+ return 2*(1-sigmap)/(1+sigmap)^(3-nu4)*T[n4+1]((2*sigma-(taus[zeta4+1]+taus[zeta4+2]))/(taus[zeta4+2]-taus[zeta4+1]))*integrate_legendre(theta->barAmat_int5(tau,sigma,taup,sigmap,theta,k,taus,T,weights,nu5,zeta5,n5),0.,2*pi,weights)
+end
+@everywhere function barAmat_int5(tau,sigma,taup,sigmap,theta,k,taus,T,weights,nu5,zeta5,n5)
+ R=barAmat_R((1-sigma)/(1+sigma),(1-tau)/(1+tau),(1-sigmap)/(1+sigmap),(1-taup)/(1+taup),theta,k)
+ if((1-R)/(1+R)<taus[zeta5+2] && (1-R)/(1+R)>taus[zeta5+1])
+ return (2/(2+R))^nu5*T[n5+1]((2*(1-R)/(1+R)-(taus[zeta5+1]+taus[zeta5+2]))/(taus[zeta5+2]-taus[zeta5+1]))
+ else
+ return 0.
+ end
+end
+# R(s,t,s',t,theta,k)
+@everywhere function barAmat_R(s,t,sp,tp,theta,k)
+ return sqrt(k^2*(s^2+t^2+sp^2+tp^2)-k^4-(s^2-t^2)*(sp^2-tp^2)-sqrt((4*k^2*s^2-(k^2+s^2-t^2)^2)*(4*k^2*sp^2-(k^2+sp^2-tp^2)^2))*cos(theta))/(sqrt(2)*k)
+end
+
+# compute Chebyshev polynomials
+@everywhere function chebyshev_polynomials(P)
+ T=Array{Polynomial}(undef,P+1)
+ T[1]=Polynomial([1])
+ T[2]=Polynomial([0,1])
+ for n in 1:P-1
+ # T_n
+ T[n+2]=2*T[2]*T[n+1]-T[n]
+ end
+
+ return T
+end
+
+# compute \int f*u dk/(2*pi)^3
+@everywhere function integrate_f_chebyshev(f,u,k,taus,weights,N,J)
+ out=0.
+ for zeta in 0:J-1
+ for i in 1:N
+ out+=(taus[zeta+2]-taus[zeta+1])/(16*pi)*weights[2][i]*cos(pi*weights[1][i]/2)*(1+k[zeta*N+i])^2*k[zeta*N+i]^2*u[zeta*N+i]*f(k[zeta*N+i])
+ end
+ end
+ return out
+end
+
+@everywhere function inverse_fourier_chebyshev(u,x,k,taus,weights,N,J)
+ out=0.
+ for zeta in 0:J-1
+ for j in 1:N
+ out+=(taus[zeta+2]-taus[zeta+1])/(16*pi*x)*weights[2][j]*cos(pi*weights[1][j]/2)*(1+k[zeta*N+j])^2*k[zeta*N+j]*u[zeta*N+j]*sin(k[zeta*N+j]*x)
+ end
+ end
+ return out
+end
diff --git a/src/easyeq.jl b/src/easyeq.jl
new file mode 100644
index 0000000..0bde3ab
--- /dev/null
+++ b/src/easyeq.jl
@@ -0,0 +1,411 @@
+## Copyright 2021 Ian Jauslin
+##
+## 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.
+
+# interpolation
+@everywhere mutable struct Easyeq_approx
+ bK::Float64
+ bL::Float64
+end
+
+# compute energy
+function easyeq_energy(minlrho_init,nlrho_init,order,rho,a0,v,maxiter,tolerance,approx)
+ # compute gaussian quadrature weights
+ weights=gausslegendre(order)
+
+ # compute initial guess from previous rho
+ (u,E,err)=easyeq_hatu(easyeq_init_u(a0,order,weights),order,(10.)^minlrho_init,v,maxiter,tolerance,weights,approx)
+ for j in 2:nlrho_init
+ rho_tmp=10^(minlrho_init+(log10(rho)-minlrho_init)*(j-1)/(nlrho_init-1))
+ (u,E,err)=easyeq_hatu(u,order,rho_tmp,v,maxiter,tolerance,weights,approx)
+ end
+
+ # print energy
+ @printf("% .15e % .15e\n",real(E),err)
+end
+
+# compute energy as a function of rho
+function easyeq_energy_rho(rhos,order,a0,v,maxiter,tolerance,approx)
+ # compute gaussian quadrature weights
+ weights=gausslegendre(order)
+ # init u
+ u=easyeq_init_u(a0,order,weights)
+
+ for j in 1:length(rhos)
+ # compute u (init newton with previously computed u)
+ (u,E,err)=easyeq_hatu(u,order,rhos[j],v,maxiter,tolerance,weights,approx)
+
+ @printf("% .15e % .15e % .15e\n",rhos[j],real(E),err)
+
+ end
+end
+
+# compute u(k)
+function easyeq_uk(minlrho_init,nlrho_init,order,rho,a0,v,maxiter,tolerance,approx)
+ weights=gausslegendre(order)
+
+ # compute initial guess from previous rho
+ (u,E,err)=easyeq_hatu(easyeq_init_u(a0,order,weights),order,(10.)^minlrho_init,v,maxiter,tolerance,weights,approx)
+ for j in 2:nlrho_init
+ rho_tmp=10^(minlrho_init+(log10(rho)-minlrho_init)*(j-1)/(nlrho_init-1))
+ (u,E,err)=easyeq_hatu(u,order,rho_tmp,v,maxiter,tolerance,weights,approx)
+ end
+
+ for i in 1:order
+ k=(1-weights[1][i])/(1+weights[1][i])
+ @printf("% .15e % .15e\n",k,real(u[i]))
+ end
+end
+
+# compute u(x)
+function easyeq_ux(minlrho_init,nlrho_init,order,rho,a0,v,maxiter,tolerance,xmin,xmax,nx,approx)
+ weights=gausslegendre(order)
+
+ # compute initial guess from previous rho
+ (u,E,err)=easyeq_hatu(easyeq_init_u(a0,order,weights),order,(10.)^minlrho_init,v,maxiter,tolerance,weights,approx)
+ for j in 2:nlrho_init
+ rho_tmp=10^(minlrho_init+(log10(rho)-minlrho_init)*(j-1)/(nlrho_init-1))
+ (u,E,err)=easyeq_hatu(u,order,rho_tmp,v,maxiter,tolerance,weights,approx)
+ end
+
+ for i in 1:nx
+ x=xmin+(xmax-xmin)*i/nx
+ @printf("% .15e % .15e\n",x,real(easyeq_u_x(x,u,weights)))
+ end
+end
+
+# compute 2u(x)-rho u*u(x)
+function easyeq_uux(minlrho_init,nlrho_init,order,rho,a0,v,maxiter,tolerance,xmin,xmax,nx,approx)
+ weights=gausslegendre(order)
+
+ # compute initial guess from previous rho
+ (u,E,err)=easyeq_hatu(easyeq_init_u(a0,order,weights),order,(10.)^minlrho_init,v,maxiter,tolerance,weights,approx)
+ for j in 2:nlrho_init
+ rho_tmp=10^(minlrho_init+(log10(rho)-minlrho_init)*(j-1)/(nlrho_init-1))
+ (u,E,err)=easyeq_hatu(u,order,rho_tmp,v,maxiter,tolerance,weights,approx)
+ end
+
+ for i in 1:nx
+ x=xmin+(xmax-xmin)*i/nx
+ @printf("% .15e % .15e\n",x,real(easyeq_u_x(x,2*u-rho*u.*u,weights)))
+ end
+end
+
+# condensate fraction
+function easyeq_condensate_fraction(minlrho_init,nlrho_init,order,rho,a0,v,maxiter,tolerance,approx)
+ # compute gaussian quadrature weights
+ weights=gausslegendre(order)
+
+ # compute initial guess from previous rho
+ (u,E,err)=easyeq_hatu(easyeq_init_u(a0,order,weights),order,(10.)^minlrho_init,v,maxiter,tolerance,weights,approx)
+ for j in 2:nlrho_init
+ rho_tmp=10^(minlrho_init+(log10(rho)-minlrho_init)*(j-1)/(nlrho_init-1))
+ (u,E,err)=easyeq_hatu(u,order,rho_tmp,v,maxiter,tolerance,weights,approx)
+ end
+
+ # compute eta
+ eta=easyeq_eta(u,order,rho,v,maxiter,tolerance,weights,approx)
+
+ # print energy
+ @printf("% .15e % .15e\n",eta,err)
+end
+
+# condensate fraction as a function of rho
+function easyeq_condensate_fraction_rho(rhos,order,a0,v,maxiter,tolerance,approx)
+ weights=gausslegendre(order)
+ # init u
+ u=easyeq_init_u(a0,order,weights)
+
+ for j in 1:length(rhos)
+ # compute u (init newton with previously computed u)
+ (u,E,err)=easyeq_hatu(u,order,rhos[j],v,maxiter,tolerance,weights,approx)
+
+ # compute eta
+ eta=easyeq_eta(u,order,rhos[j],v,maxiter,tolerance,weights,approx)
+
+ @printf("% .15e % .15e % .15e\n",rhos[j],eta,err)
+ end
+end
+
+
+# initialize u
+@everywhere function easyeq_init_u(a0,order,weights)
+ u=zeros(Float64,order)
+ for j in 1:order
+ # transformed k
+ k=(1-weights[1][j])/(1+weights[1][j])
+ u[j]=4*pi*a0/k^2
+ end
+
+ return u
+end
+
+# \hat u(k) computed using Newton
+@everywhere function easyeq_hatu(u0,order,rho,v,maxiter,tolerance,weights,approx)
+ # initialize V and Eta
+ (V,V0)=easyeq_init_v(weights,v)
+ (Eta,Eta0)=easyeq_init_H(weights,v)
+
+ # init u
+ u=rho*u0
+
+ # iterate
+ err=Inf
+ for i in 1:maxiter-1
+ new=u-inv(easyeq_dXi(u,V,V0,Eta,Eta0,weights,rho,approx))*easyeq_Xi(u,V,V0,Eta,Eta0,weights,rho,approx)
+
+ err=norm(new-u)/norm(u)
+ if(err<tolerance)
+ u=new
+ break
+ end
+ u=new
+ end
+
+ return (u/rho,easyeq_en(u,V0,Eta0,rho,weights)*rho/2,err)
+end
+
+# \Eta
+@everywhere function easyeq_H(x,t,weights,v)
+ return (x>t ? 2*t/x : 2)* integrate_legendre(y->2*pi*((x+t)*y+abs(x-t)*(1-y))*v((x+t)*y+abs(x-t)*(1-y)),0,1,weights)
+end
+
+# initialize V
+@everywhere function easyeq_init_v(weights,v)
+ order=length(weights[1])
+ V=Array{Float64}(undef,order)
+ V0=v(0)
+ for i in 1:order
+ k=(1-weights[1][i])/(1+weights[1][i])
+ V[i]=v(k)
+ end
+ return(V,V0)
+end
+
+# initialize Eta
+@everywhere function easyeq_init_H(weights,v)
+ order=length(weights[1])
+ Eta=Array{Array{Float64}}(undef,order)
+ Eta0=Array{Float64}(undef,order)
+ for i in 1:order
+ k=(1-weights[1][i])/(1+weights[1][i])
+ Eta[i]=Array{Float64}(undef,order)
+ for j in 1:order
+ y=(weights[1][j]+1)/2
+ Eta[i][j]=easyeq_H(k,(1-y)/y,weights,v)
+ end
+ y=(weights[1][i]+1)/2
+ Eta0[i]=easyeq_H(0,(1-y)/y,weights,v)
+ end
+ return(Eta,Eta0)
+end
+
+# Xi(u)
+@everywhere function easyeq_Xi(u,V,V0,Eta,Eta0,weights,rho,approx)
+ order=length(weights[1])
+
+ # init
+ out=zeros(Float64,order)
+
+ # compute E before running the loop
+ E=easyeq_en(u,V0,Eta0,rho,weights)
+
+ for i in 1:order
+ # k_i
+ k=(1-weights[1][i])/(1+weights[1][i])
+ # S_i
+ S=V[i]-1/(rho*(2*pi)^3)*integrate_legendre_sampled(y->(1-y)/y^3,Eta[i].*u,0,1,weights)
+
+ # A_K,i
+ A=0.
+ if approx.bK!=0.
+ A+=approx.bK*S
+ end
+ if approx.bK!=1.
+ A+=(1-approx.bK)*E
+ end
+
+ # T
+ if approx.bK==1.
+ T=1.
+ else
+ T=S/A
+ end
+
+ # B
+ if approx.bK==approx.bL
+ B=1.
+ else
+ B=(approx.bL*S+(1-approx.bL*E))/(approx.bK*S+(1-approx.bK*E))
+ end
+
+ # X_i
+ X=k^2/(2*A*rho)
+
+ # U_i
+ out[i]=u[i]-T/(2*(X+1))*Phi(B*T/(X+1)^2)
+ end
+
+ return out
+end
+
+# derivative of Xi
+@everywhere function easyeq_dXi(u,V,V0,Eta,Eta0,weights,rho,approx)
+ order=length(weights[1])
+
+ # init
+ out=zeros(Float64,order,order)
+
+ # compute E before the loop
+ E=easyeq_en(u,V0,Eta0,rho,weights)
+
+ for i in 1:order
+ # k_i
+ k=(1-weights[1][i])/(1+weights[1][i])
+ # S_i
+ S=V[i]-1/(rho*(2*pi)^3)*integrate_legendre_sampled(y->(1-y)/y^3,Eta[i].*u,0,1,weights)
+
+ # A_K,i
+ A=0.
+ if approx.bK!=0.
+ A+=approx.bK*S
+ end
+ if approx.bK!=1.
+ A+=(1-approx.bK)*E
+ end
+
+ # T
+ if approx.bK==1.
+ T=1.
+ else
+ T=S/A
+ end
+
+ # B
+ if approx.bK==approx.bL
+ B=1.
+ else
+ B=(approx.bL*S+(1-approx.bL*E))/(approx.bK*S+(1-approx.bK*E))
+ end
+
+ # X_i
+ X=k^2/(2*A*rho)
+
+ for j in 1:order
+ y=(weights[1][j]+1)/2
+ dS=-1/rho*(1-y)*Eta[i][j]/(2*(2*pi)^3*y^3)*weights[2][j]
+ dE=-1/rho*(1-y)*Eta0[j]/(2*(2*pi)^3*y^3)*weights[2][j]
+
+ # dA
+ dA=0.
+ if approx.bK!=0.
+ dA+=approx.bK*dS
+ end
+ if approx.bK!=1.
+ dA+=(1-approx.bK)*dE
+ end
+
+ # dT
+ if approx.bK==1.
+ dT=0.
+ else
+ dT=(1-approx.bK)*(E*dS-S*dE)/A^2
+ end
+
+ # dB
+ if approx.bK==approx.bL
+ dB=0.
+ else
+ dB=(approx.bL*(1-approx.bK)-approx.bK*(1-approx.bL))*(E*dS-S*dE)/(approx.bK*S+(1-approx.bK*E))^2
+ end
+
+ dX=-k^2/(2*A^2*rho)*dA
+
+ out[i,j]=(i==j ? 1 : 0)-(dT-T*dX/(X+1))/(2*(X+1))*Phi(B*T/(X+1)^2)-T/(2*(X+1)^3)*(B*dT+T*dB-2*B*T*dX/(X+1))*dPhi(B*T/(X+1)^2)
+ end
+ end
+
+ return out
+end
+
+# derivative of Xi with respect to mu
+@everywhere function easyeq_dXidmu(u,V,V0,Eta,Eta0,weights,rho,approx)
+ order=length(weights[1])
+
+ # init
+ out=zeros(Float64,order)
+
+ # compute E before running the loop
+ E=easyeq_en(u,V0,Eta0,rho,weights)
+
+ for i in 1:order
+ # k_i
+ k=(1-weights[1][i])/(1+weights[1][i])
+ # S_i
+ S=V[i]-1/(rho*(2*pi)^3)*integrate_legendre_sampled(y->(1-y)/y^3,Eta[i].*u,0,1,weights)
+
+ # A_K,i
+ A=0.
+ if approx.bK!=0.
+ A+=approx.bK*S
+ end
+ if approx.bK!=1.
+ A+=(1-approx.bK)*E
+ end
+
+ # T
+ if approx.bK==1.
+ T=1.
+ else
+ T=S/A
+ end
+
+ # B
+ if approx.bK==approx.bL
+ B=1.
+ else
+ B=(approx.bL*S+(1-approx.bL*E))/(approx.bK*S+(1-approx.bK*E))
+ end
+
+ # X_i
+ X=k^2/(2*A*rho)
+
+ out[i]=T/(2*rho*A*(X+1)^2)*Phi(B*T/(X+1)^2)+B*T^2/(rho*A*(X+1)^4)*dPhi(B*T/(X+1)^2)
+ end
+
+ return out
+end
+
+# energy
+@everywhere function easyeq_en(u,V0,Eta0,rho,weights)
+ return V0-1/(rho*(2*pi)^3)*integrate_legendre_sampled(y->(1-y)/y^3,Eta0.*u,0,1,weights)
+end
+
+# condensate fraction
+@everywhere function easyeq_eta(u,order,rho,v,maxiter,tolerance,weights,approx)
+ (V,V0)=easyeq_init_v(weights,v)
+ (Eta,Eta0)=easyeq_init_H(weights,v)
+
+ du=-inv(easyeq_dXi(rho*u,V,V0,Eta,Eta0,weights,rho,approx))*easyeq_dXidmu(rho*u,V,V0,Eta,Eta0,weights,rho,approx)
+
+ eta=-1/(2*(2*pi)^3)*integrate_legendre_sampled(y->(1-y)/y^3,Eta0.*du,0,1,weights)
+
+ return eta
+end
+
+# inverse Fourier transform
+@everywhere function easyeq_u_x(x,u,weights)
+ order=length(weights[1])
+ out=integrate_legendre_sampled(y->(1-y)/y^3*sin(x*(1-y)/y)/x/(2*pi^2),u,0,1,weights)
+ return out
+end
diff --git a/src/integration.jl b/src/integration.jl
new file mode 100644
index 0000000..9be4641
--- /dev/null
+++ b/src/integration.jl
@@ -0,0 +1,58 @@
+## Copyright 2021 Ian Jauslin
+##
+## 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.
+
+# approximate \int_a^b f using Gauss-Legendre quadratures
+@everywhere function integrate_legendre(f,a,b,weights)
+ out=0
+ for i in 1:length(weights[1])
+ out+=(b-a)/2*weights[2][i]*f((b-a)/2*weights[1][i]+(b+a)/2)
+ end
+ return out
+end
+# \int f*g where g is sampled at the Legendre nodes
+@everywhere function integrate_legendre_sampled(f,g,a,b,weights)
+ out=0
+ for i in 1:length(weights[1])
+ out+=(b-a)/2*weights[2][i]*f((b-a)/2*weights[1][i]+(b+a)/2)*g[i]
+ end
+ return out
+end
+
+
+# approximate \int_a^b f/sqrt((b-x)(x-a)) using Gauss-Chebyshev quadratures
+@everywhere function integrate_chebyshev(f,a,b,N)
+ out=0
+ for i in 1:N
+ out=out+pi/N*f((b-a)/2*cos((2*i-1)/(2*N)*pi)+(b+a)/2)
+ end
+ return out
+end
+
+# approximate \int_0^\infty dr f(r)*exp(-a*r) using Gauss-Chebyshev quadratures
+@everywhere function integrate_laguerre(f,a,weights_gL)
+ out=0.
+ for i in 1:length(weights_gL[1])
+ out+=1/a*f(weights_gL[1][i]/a)*weights_gL[2][i]
+ end
+ return out
+end
+
+# Hann window
+@everywhere function hann(x,L)
+ if abs(x)<L/2
+ return cos(pi*x/L)^2
+ else
+ return 0.
+ end
+end
diff --git a/src/interpolation.jl b/src/interpolation.jl
new file mode 100644
index 0000000..fa3bcdb
--- /dev/null
+++ b/src/interpolation.jl
@@ -0,0 +1,108 @@
+## Copyright 2021 Ian Jauslin
+##
+## 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.
+
+# linear interpolation: given vectors x,y, compute a linear interpolation for y(x0)
+# assume x is ordered
+@everywhere function linear_interpolation(x0,x,y)
+ # if x0 is beyond all x's, then return the corresponding boundary value.
+ if x0>x[length(x)]
+ return y[length(y)]
+ elseif x0<x[1]
+ return y[1]
+ end
+
+ # find bracketing interval
+ i=bracket(x0,x,1,length(x))
+
+ # interpolate
+ return y[i]+(y[i+1]-y[i])*(x0-x[i])/(x[i+1]-x[i])
+end
+@everywhere function bracket(x0,x,a,b)
+ i=floor(Int64,(a+b)/2)
+ if x0<x[i]
+ return bracket(x0,x,a,i)
+ elseif x0>x[i+1]
+ return bracket(x0,x,i+1,b)
+ else
+ return i
+ end
+end
+
+
+# polynomial interpolation of a family of points
+@everywhere function poly_interpolation(x,y)
+ # init for recursion
+ rec=Array{Polynomial{Float64}}(undef,length(x))
+ for i in 1:length(x)
+ rec[i]=Polynomial([1.])
+ end
+
+ # compute \prod (x-x_i)
+ poly_interpolation_rec(rec,x,1,length(x))
+
+ # sum terms together
+ out=0.
+ for i in 1:length(y)
+ out+=rec[i]/rec[i](x[i])*y[i]
+ end
+
+ return out
+end
+# recursive helper function
+@everywhere function poly_interpolation_rec(out,x,a,b)
+ if a==b
+ return
+ end
+ # mid point
+ mid=floor(Int64,(a+b)/2)
+ # multiply left and right of mid
+ right=Polynomial([1.])
+ for i in mid+1:b
+ right*=Polynomial([-x[i],1.])
+ end
+ left=Polynomial([1.])
+ for i in a:mid
+ left*=Polynomial([-x[i],1.])
+ end
+
+ # multiply into left and right
+ for i in a:mid
+ out[i]*=right
+ end
+ for i in mid+1:b
+ out[i]*=left
+ end
+
+ # recurse
+ poly_interpolation_rec(out,x,a,mid)
+ poly_interpolation_rec(out,x,mid+1,b)
+
+ return
+end
+## the following does the same, but has complexity N^2, the function above has N*log(N)
+#@everywhere function poly_interpolation(x,y)
+# out=Polynomial([0.])
+# for i in 1:length(x)
+# prod=Polynomial([1.])
+# for j in 1:length(x)
+# if j!=i
+# prod*=Polynomial([-x[j]/(x[i]-x[j]),1/(x[i]-x[j])])
+# end
+# end
+# out+=prod*y[i]
+# end
+#
+# return out
+#end
+
diff --git a/src/main.jl b/src/main.jl
new file mode 100644
index 0000000..382fe6b
--- /dev/null
+++ b/src/main.jl
@@ -0,0 +1,443 @@
+## Copyright 2021 Ian Jauslin
+##
+## 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.
+
+using Distributed
+@everywhere using FastGaussQuadrature
+@everywhere using LinearAlgebra
+@everywhere using Polynomials
+@everywhere using Printf
+@everywhere using SpecialFunctions
+include("chebyshev.jl")
+include("integration.jl")
+include("interpolation.jl")
+include("tools.jl")
+include("potentials.jl")
+include("print.jl")
+include("easyeq.jl")
+include("simpleq-Kv.jl")
+include("simpleq-iteration.jl")
+include("simpleq-hardcore.jl")
+include("anyeq.jl")
+function main()
+ ## defaults
+
+ # values of rho,e, when needed
+ rho=1e-6
+ e=1e-4
+
+ # incrementally initialize Newton algorithm
+ nlrho_init=1
+
+ # potential
+ v=k->v_exp(k,1.)
+ a0=a0_exp(1.)
+ # arguments of the potential
+ v_param_a=1.
+ v_param_b=1.
+ v_param_c=1.
+ v_param_e=1.
+
+ # plot range when plotting in rho
+ minlrho=-6
+ maxlrho=2
+ nlrho=100
+ rhos=Array{Float64}(undef,0)
+ # plot range when plotting in e
+ minle=-6
+ maxle=2
+ nle=100
+ es=Array{Float64}(undef,0)
+ # plot range when plotting in x
+ xmin=0
+ xmax=100
+ nx=100
+
+ # cutoffs
+ tolerance=1e-11
+ order=100
+ maxiter=21
+
+ # for anyeq
+ # P
+ P=11
+ # N
+ N=12
+ # number of splines
+ J=10
+
+ # starting rho from which to incrementally initialize Newton algorithm
+ # default must be set after reading rho, if not set explicitly
+ minlrho_init=nothing
+
+ # Hann window for Fourier transforms
+ windowL=1e3
+
+ # approximation for easyeq
+ # bK,bL
+ easyeq_simpleq_approx=Easyeq_approx(0.,0.)
+ easyeq_medeq_approx=Easyeq_approx(1.,1.)
+ easyeq_approx=easyeq_simpleq_approx
+
+ # approximation for anyeq
+ # aK,bK,gK,aL1,bL1,aL2,bL2,gL2,aL3,bL3,gl3
+ anyeq_simpleq_approx=Anyeq_approx(0.,0.,1.,0.,0.,0.,0.,0.,0.,0.,0.)
+ anyeq_bigeq_approx=Anyeq_approx(1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.)
+ anyeq_fulleq_approx=Anyeq_approx(1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.)
+ anyeq_medeq_approx=Anyeq_approx(0.,1.,1.,0.,1.,0.,0.,0.,0.,0.,0.)
+ anyeq_compleq_approx=Anyeq_approx(1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.)
+ anyeq_approx=anyeq_bigeq_approx
+
+ # read cli arguments
+ (params,potential,method,savefile,command)=read_args(ARGS)
+
+ # read params
+ if params!=""
+ for param in split(params,";")
+ terms=split(param,"=")
+ if length(terms)!=2
+ print(stderr,"error: could not read parameter '",param,"'.\n")
+ exit(-1)
+ end
+ lhs=terms[1]
+ rhs=terms[2]
+ if lhs=="rho"
+ rho=parse(Float64,rhs)
+ elseif lhs=="minlrho_init"
+ minlrho_init=parse(Float64,rhs)
+ elseif lhs=="nlrho_init"
+ nlrho_init=parse(Int64,rhs)
+ elseif lhs=="e"
+ e=parse(Float64,rhs)
+ elseif lhs=="tolerance"
+ tolerance=parse(Float64,rhs)
+ elseif lhs=="order"
+ order=parse(Int64,rhs)
+ elseif lhs=="maxiter"
+ maxiter=parse(Int64,rhs)
+ elseif lhs=="rhos"
+ rhos=parse_list(rhs)
+ elseif lhs=="minlrho"
+ minlrho=parse(Float64,rhs)
+ elseif lhs=="maxlrho"
+ maxlrho=parse(Float64,rhs)
+ elseif lhs=="nlrho"
+ nlrho=parse(Int64,rhs)
+ elseif lhs=="es"
+ es=parse_list(rhs)
+ elseif lhs=="minle"
+ minle=parse(Float64,rhs)
+ elseif lhs=="maxle"
+ maxle=parse(Float64,rhs)
+ elseif lhs=="nle"
+ nle=parse(Int64,rhs)
+ elseif lhs=="xmin"
+ xmin=parse(Float64,rhs)
+ elseif lhs=="xmax"
+ xmax=parse(Float64,rhs)
+ elseif lhs=="nx"
+ nx=parse(Int64,rhs)
+ elseif lhs=="P"
+ P=parse(Int64,rhs)
+ elseif lhs=="N"
+ N=parse(Int64,rhs)
+ elseif lhs=="J"
+ J=parse(Int64,rhs)
+ elseif lhs=="window_L"
+ windowL=parse(Float64,rhs)
+ elseif lhs=="aK"
+ anyeq_approx.aK=parse(Float64,rhs)
+ elseif lhs=="bK"
+ anyeq_approx.bK=parse(Float64,rhs)
+ easyeq_approx.bK=parse(Float64,rhs)
+ elseif lhs=="gK"
+ anyeq_approx.gK=parse(Float64,rhs)
+ elseif lhs=="aL1"
+ anyeq_approx.aL1=parse(Float64,rhs)
+ elseif lhs=="bL"
+ easyeq_approx.bL=parse(Float64,rhs)
+ elseif lhs=="bL1"
+ anyeq_approx.bL1=parse(Float64,rhs)
+ elseif lhs=="aL2"
+ anyeq_approx.aL2=parse(Float64,rhs)
+ elseif lhs=="bL2"
+ anyeq_approx.bL2=parse(Float64,rhs)
+ elseif lhs=="gL2"
+ anyeq_approx.gL2=parse(Float64,rhs)
+ elseif lhs=="aL3"
+ anyeq_approx.aL3=parse(Float64,rhs)
+ elseif lhs=="bL3"
+ anyeq_approx.bL3=parse(Float64,rhs)
+ elseif lhs=="gL3"
+ anyeq_approx.gL3=parse(Float64,rhs)
+ elseif lhs=="v_a"
+ v_param_a=parse(Float64,rhs)
+ elseif lhs=="v_b"
+ v_param_b=parse(Float64,rhs)
+ elseif lhs=="v_c"
+ v_param_c=parse(Float64,rhs)
+ elseif lhs=="v_e"
+ v_param_e=parse(Float64,rhs)
+ elseif lhs=="eq"
+ if rhs=="simpleq"
+ easyeq_approx=easyeq_simpleq_approx
+ anyeq_approx=anyeq_simpleq_approx
+ elseif rhs=="medeq"
+ easyeq_approx=easyeq_medeq_approx
+ anyeq_approx=anyeq_medeq_approx
+ elseif rhs=="bigeq"
+ anyeq_approx=anyeq_bigeq_approx
+ elseif rhs=="fulleq"
+ anyeq_approx=anyeq_fulleq_approx
+ elseif rhs=="compleq"
+ anyeq_approx=anyeq_compleq_approx
+ else
+ print(stderr,"error: unrecognized equation: ",rhs,"\n")
+ exit(-1)
+ end
+ else
+ print(stderr,"unrecognized parameter '",lhs,"'.\n")
+ exit(-1)
+ end
+ end
+ end
+
+ ## read potential
+ if potential=="exp"
+ v=k->v_exp(k,v_param_a)
+ a0=a0_exp(v_param_a)
+ elseif potential=="expcry"
+ v=k->v_expcry(k,v_param_a,v_param_b)
+ a0=a0_expcry(v_param_a,v_param_b)
+ elseif potential=="npt"
+ v=k->v_npt(k)
+ a0=a0_npt()
+ elseif potential=="alg"
+ v=v_alg
+ a0=a0_alg
+ elseif potential=="algwell"
+ v=v_algwell
+ a0=a0_algwell
+ elseif potential=="exact"
+ v=k->v_exact(k,v_param_b,v_param_c,v_param_e)
+ a0=a0_exact(v_param_b,v_param_c,v_param_e)
+ elseif potential=="tent"
+ v=k->v_tent(k,v_param_a,v_param_b)
+ a0=a0_tent(v_param_a,v_param_b)
+ else
+ print(stderr,"unrecognized potential '",potential,"'.\n'")
+ exit(-1)
+ end
+
+ ## set parameters
+ # rhos
+ if length(rhos)==0
+ rhos=Array{Float64}(undef,nlrho)
+ for j in 0:nlrho-1
+ rhos[j+1]=(nlrho==1 ? 10^minlrho : 10^(minlrho+(maxlrho-minlrho)/(nlrho-1)*j))
+ end
+ end
+ # es
+ if length(es)==0
+ es=Array{Float64}(undef,nle)
+ for j in 0:nle-1
+ es[j+1]=(nle==1 ? 10^minle : 10^(minle+(maxle-minle)/(nle-1)*j))
+ end
+ end
+
+ # default minlrho_init
+ if (minlrho_init==nothing)
+ minlrho_init=log10(rho)
+ end
+
+ # splines
+ taus=Array{Float64}(undef,J+1)
+ for j in 0:J
+ taus[j+1]=-1+2*j/J
+ end
+
+ ## run command
+ if method=="easyeq"
+ if command=="energy"
+ easyeq_energy(minlrho_init,nlrho_init,order,rho,a0,v,maxiter,tolerance,easyeq_approx)
+ # e(rho)
+ elseif command=="energy_rho"
+ easyeq_energy_rho(rhos,order,a0,v,maxiter,tolerance,easyeq_approx)
+ # u(k)
+ elseif command=="uk"
+ easyeq_uk(minlrho_init,nlrho_init,order,rho,a0,v,maxiter,tolerance,easyeq_approx)
+ # u(x)
+ elseif command=="ux"
+ easyeq_ux(minlrho_init,nlrho_init,order,rho,a0,v,maxiter,tolerance,xmin,xmax,nx,easyeq_approx)
+ elseif command=="uux"
+ easyeq_uux(minlrho_init,nlrho_init,order,rho,a0,v,maxiter,tolerance,xmin,xmax,nx,easyeq_approx)
+ # condensate fraction
+ elseif command=="condensate_fraction"
+ easyeq_condensate_fraction(minlrho_init,nlrho_init,order,rho,a0,v,maxiter,tolerance,easyeq_approx)
+ elseif command=="condensate_fraction_rho"
+ easyeq_condensate_fraction_rho(rhos,order,a0,v,maxiter,tolerance,easyeq_approx)
+ else
+ print(stderr,"unrecognized command '",command,"'.\n")
+ exit(-1)
+ end
+ elseif method=="simpleq-hardcore"
+ if command=="energy_rho"
+ simpleq_hardcore_energy_rho(rhos,taus,P,N,J,maxiter,tolerance)
+ elseif command=="ux"
+ simpleq_hardcore_ux(rho,taus,P,N,J,maxiter,tolerance)
+ elseif command=="condensate_fraction_rho"
+ simpleq_hardcore_condensate_fraction_rho(rhos,taus,P,N,J,maxiter,tolerance)
+ end
+ elseif method=="simpleq-iteration"
+ # u_n(x) using iteration
+ if command=="u"
+ simpleq_iteration_ux(order,e,v,maxiter,xmin,xmax,nx)
+ # rho(e) using iteration
+ elseif command=="rho_e"
+ simpleq_iteration_rho_e(es,order,v,maxiter)
+ else
+ print(stderr,"unrecognized command '",command,"'.\n")
+ exit(-1)
+ end
+ elseif method=="anyeq"
+ if command=="save_Abar"
+ anyeq_save_Abar(taus,P,N,J,v,anyeq_approx)
+ elseif command=="energy"
+ anyeq_energy(rho,minlrho_init,nlrho_init,taus,P,N,J,a0,v,maxiter,tolerance,anyeq_approx,savefile)
+ # e(rho)
+ elseif command=="energy_rho"
+ anyeq_energy_rho(rhos,taus,P,N,J,a0,v,maxiter,tolerance,anyeq_approx,savefile)
+ elseif command=="energy_rho_init_prevrho"
+ anyeq_energy_rho_init_prevrho(rhos,taus,P,N,J,a0,v,maxiter,tolerance,anyeq_approx,savefile)
+ elseif command=="energy_rho_init_nextrho"
+ anyeq_energy_rho_init_nextrho(rhos,taus,P,N,J,a0,v,maxiter,tolerance,anyeq_approx,savefile)
+ # u(j)
+ elseif command=="uk"
+ anyeq_uk(minlrho_init,nlrho_init,taus,P,N,J,rho,a0,v,maxiter,tolerance,anyeq_approx,savefile)
+ # u(j)
+ elseif command=="ux"
+ anyeq_ux(minlrho_init,nlrho_init,taus,P,N,J,rho,a0,v,maxiter,tolerance,xmin,xmax,nx,anyeq_approx,savefile)
+ # condensate fraction
+ elseif command=="condensate_fraction"
+ anyeq_condensate_fraction(rho,minlrho_init,nlrho_init,taus,P,N,J,a0,v,maxiter,tolerance,anyeq_approx,savefile)
+ elseif command=="condensate_fraction_rho"
+ anyeq_condensate_fraction_rho(rhos,taus,P,N,J,a0,v,maxiter,tolerance,anyeq_approx,savefile)
+ # momentum distribution
+ elseif command=="momentum_distribution"
+ anyeq_momentum_distribution(rho,minlrho_init,nlrho_init,taus,P,N,J,a0,v,maxiter,tolerance,anyeq_approx,savefile)
+ elseif command=="2pt"
+ anyeq_2pt_correlation(minlrho_init,nlrho_init,taus,P,N,J,windowL,rho,a0,v,maxiter,tolerance,xmin,xmax,nx,anyeq_approx,savefile)
+ else
+ print(stderr,"unrecognized command: '",command,"'\n")
+ exit(-1)
+ end
+ elseif method=="simpleq-Kv"
+ if command=="2pt"
+ simpleq_Kv_2pt(minlrho_init,nlrho_init,taus,P,N,J,rho,a0,v,maxiter,tolerance,xmin,xmax,nx)
+ elseif command=="condensate_fraction_rho"
+ simpleq_Kv_condensate_fraction(rhos,taus,P,N,J,a0,v,maxiter,tolerance)
+ elseif command=="Kv"
+ simpleq_Kv_Kv(minlrho_init,nlrho_init,taus,P,N,J,rho,a0,v,maxiter,tolerance,xmin,xmax,nx)
+ else
+ print(stderr,"unrecognized command: '",command,"'\n")
+ exit(-1)
+ end
+ else
+ print(stderr,"unrecognized method: '",method,"'\n")
+ exit(-1)
+ end
+
+end
+
+# parse a comma separated list as an array of Float64
+function parse_list(str)
+ elems=split(str,",")
+ out=Array{Float64}(undef,length(elems))
+ for i in 1:length(elems)
+ out[i]=parse(Float64,elems[i])
+ end
+ return out
+end
+
+# read cli arguments
+function read_args(ARGS)
+ # flag
+ flag=""
+
+ # output strings
+ params=""
+ # default potential
+ potential="exp"
+ # default method
+ method="easyeq"
+
+ savefile=""
+ command=""
+
+ # loop over arguments
+ for arg in ARGS
+ # argument that starts with a dash
+ if arg[1]=='-'
+ # go through characters after dash
+ for char in arg[2:length(arg)]
+
+ # set params
+ if char=='p'
+ # raise flag
+ flag="params"
+ elseif char=='U'
+ # raise flag
+ flag="potential"
+ elseif char=='M'
+ # raise flag
+ flag="method"
+ elseif char=='s'
+ # raise flag
+ flag="savefile"
+ else
+ print_usage()
+ exit(-1)
+ end
+ end
+ # arguments that do not start with a dash
+ else
+ if flag=="params"
+ params=arg
+ elseif flag=="potential"
+ potential=arg
+ elseif flag=="method"
+ method=arg
+ elseif flag=="savefile"
+ savefile=arg
+ else
+ command=arg
+ end
+ # reset flag
+ flag=""
+ end
+ end
+
+ if command==""
+ print_usage()
+ exit(-1)
+ end
+
+ return (params,potential,method,savefile,command)
+end
+
+# usage
+function print_usage()
+ print(stderr,"usage: simplesolv [-p params] [-U potential] [-M method] [-s savefile] <command>\n")
+end
+
+main()
diff --git a/src/potentials.jl b/src/potentials.jl
new file mode 100644
index 0000000..46cafc0
--- /dev/null
+++ b/src/potentials.jl
@@ -0,0 +1,84 @@
+## Copyright 2021 Ian Jauslin
+##
+## 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.
+
+# exponential potential in 3 dimensions
+@everywhere function v_exp(k,a)
+ return 8*pi/(1+k^2)^2*a
+end
+@everywhere function a0_exp(a)
+ if a>0.
+ return log(a)+2*MathConstants.eulergamma+2*besselk(0,2*sqrt(a))/besseli(0,2*sqrt(a))
+ elseif a<0.
+ return log(-a)+2*MathConstants.eulergamma-pi*bessely(0,2*sqrt(-a))/besselj(0,2*sqrt(-a))
+ else
+ return 0.
+ end
+end
+
+# exp(-x)-a*exp(-b*x) in 3 dimensions
+@everywhere function v_expcry(k,a,b)
+ return 8*pi*((1+k^2)^(-2)-a*b*(b^2+k^2)^(-2))
+end
+@everywhere function a0_expcry(a,b)
+ return 1.21751642717932720441274114683413710125487579284827462 #ish
+end
+
+# x^2*exp(-|x|) in 3 dimensions
+@everywhere function v_npt(k)
+ return 96*pi*(1-k^2)/(1+k^2)^4
+end
+@everywhere function a0_npt()
+ return 1. #ish
+end
+
+# 1/(1+x^4/4) potential in 3 dimensions
+@everywhere function v_alg(k)
+ if(k==0)
+ return 4*pi^2
+ else
+ return 4*pi^2*exp(-k)*sin(k)/k
+ end
+end
+a0_alg=1. #ish
+
+# (1+a x^4)/(1+x^2)^4 potential in 3 dimensions
+@everywhere function v_algwell(k)
+ a=4
+ return pi^2/24*exp(-k)*(a*(k^2-9*k+15)+k^2+3*k+3)
+end
+a0_algwell=1. #ish
+
+# potential corresponding to the exact solution c/(1+b^2x^2)^2
+@everywhere function v_exact(k,b,c,e)
+ if k!=0
+ return 48*pi^2*((18+3*sqrt(c)-(4-3*e/b^2)*c-(1-2*e/b^2)*c^1.5)/(4*(3+sqrt(c))^2*sqrt(c))*exp(-sqrt(1-sqrt(c))*k/b)+(-18+3*sqrt(c)+(4-3*e/b^2)*c-(1-2*e/b^2)*c^1.5)/(4*(3-sqrt(c))^2*sqrt(c))*exp(-sqrt(1+sqrt(c))*k/b)+(1-k/b)/2*exp(-k/b)-c*e/b^2*(3*(9-c)*k/b+8*c)/(8*(9-c)^2)*exp(-2*k/b))/k
+ else
+ return 48*pi^2*(-sqrt(1-sqrt(c))/b*(18+3*sqrt(c)-(4-3*e/b^2)*c-(1-2*e/b^2)*c^1.5)/(4*(3+sqrt(c))^2*sqrt(c))-sqrt(1+sqrt(c))/b*(-18+3*sqrt(c)+(4-3*e/b^2)*c-(1-2*e/b^2)*c^1.5)/(4*(3-sqrt(c))^2*sqrt(c))-1/b-c*e/b^2*(27-19*c)/(8*(9-c)^2))
+ end
+end
+@everywhere function a0_exact(b,c,e)
+ return 1. #ish
+end
+
+# tent potential (convolution of soft sphere with itself): a*pi/12*(2*|x|/b-2)^2*(2*|x|/b+4) for |x|<b
+@everywhere function v_tent(k,a,b)
+ if k!=0
+ return (b/2)^3*a*(4*pi*(sin(k*b/2)-k*b/2*cos(k*b/2))/(k*b/2)^3)^2
+ else
+ return (b/2)^3*a*(4*pi/3)^2
+ end
+end
+@everywhere function a0_tent(a,b)
+ return b #ish
+end
diff --git a/src/print.jl b/src/print.jl
new file mode 100644
index 0000000..bef1c4d
--- /dev/null
+++ b/src/print.jl
@@ -0,0 +1,52 @@
+## Copyright 2021 Ian Jauslin
+##
+## 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.
+
+# print progress
+@everywhere function progress(
+ j::Int64,
+ tot::Int64,
+ freq::Int64
+)
+ if (j-1)%ceil(Int,tot/freq)==0
+ if j>1
+ @printf(stderr,"\r")
+ end
+ @printf(stderr,"%d/%d",j,tot)
+ end
+ if j==tot
+ @printf(stderr,"\r")
+ @printf(stderr,"%d/%d\n",j,tot)
+ end
+end
+
+# print progress of two indices at once
+@everywhere function progress_mat(
+ j1::Int64,
+ tot1::Int64,
+ j2::Int64,
+ tot2::Int64,
+ freq::Int64
+)
+ if ((j1-1)*tot2+j2-1)%ceil(Int,tot1*tot2/freq)==0
+ if j1>1 || j2>1
+ @printf(stderr,"\r")
+ end
+ @printf(stderr,"%2d/%2d, %2d/%2d",j1,tot1,j2,tot2)
+ end
+ if j1==tot1 && j2==tot2
+ @printf(stderr,"\r")
+ @printf(stderr,"%2d/%2d, %2d/%2d\n",j1,tot1,j2,tot2)
+ end
+end
+
diff --git a/src/simpleq-Kv.jl b/src/simpleq-Kv.jl
new file mode 100644
index 0000000..8789656
--- /dev/null
+++ b/src/simpleq-Kv.jl
@@ -0,0 +1,119 @@
+## Copyright 2021 Ian Jauslin
+##
+## 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.
+
+# Compute Kv=(-\Delta+v+4e(1-\rho u*))^{-1}v
+function anyeq_Kv(minlrho,nlrho,taus,P,N,J,rho,a0,v,maxiter,tolerance,xmin,xmax,nx)
+ # init vectors
+ (weights,T,k,V,V0,A,Upsilon,Upsilon0)=anyeq_init(taus,P,N,J,v)
+
+ # compute initial guess from medeq
+ rhos=Array{Float64}(undef,nlrho)
+ for j in 0:nlrho-1
+ rhos[j+1]=(nlrho==1 ? rho : 10^(minlrho+(log10(rho)-minlrho)/(nlrho-1)*j))
+ end
+ u0s=anyeq_init_medeq(rhos,N,J,k,a0,v,maxiter,tolerance)
+ u0=u0s[nlrho]
+
+ (u,E,error)=anyeq_hatu(u0,P,N,J,rho,a0,weights,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,v,maxiter,tolerance,Anyeq_approx(0.,0.,1.,0.,0.,0.,0.,0.,0.,0.,0.))
+
+ # Kv in Fourier space
+ Kvk=simpleq_Kv_Kvk(u,V,E,rho,Upsilon,k,taus,weights,N,J)
+
+ # switch to real space
+ for i in 1:nx
+ x=xmin+(xmax-xmin)*i/nx
+ Kv=0.
+ for zeta in 0:J-1
+ for j in 1:N
+ Kv+=(taus[zeta+2]-taus[zeta+1])/(16*pi*x)*weights[2][j]*cos(pi*weights[1][j]/2)*(1+k[zeta*N+j])^2*k[zeta*N+j]*Kvk[zeta*N+j]*sin(k[zeta*N+j]*x)
+ end
+ end
+ @printf("% .15e % .15e\n",x,Kv)
+ end
+end
+
+# Compute the condensate fraction for simpleq using Kv
+function simpleq_Kv_condensate_fraction(rhos,taus,P,N,J,a0,v,maxiter,tolerance)
+ # init vectors
+ (weights,T,k,V,V0,A,Upsilon,Upsilon0)=anyeq_init(taus,P,N,J,v)
+
+ # compute initial guess from medeq
+ u0s=anyeq_init_medeq(rhos,N,J,k,a0,v,0.,maxiter,tolerance)
+
+ for j in 1:length(rhos)
+ (u,E,error)=anyeq_hatu(u0s[j],0.,P,N,J,rhos[j],a0,weights,k,taus,V,V0,A,Abar,Upsilon,Upsilon0,v,maxiter,tolerance,Anyeq_approx(0.,0.,1.,0.,0.,0.,0.,0.,0.,0.,0.))
+
+ # Kv in Fourier space
+ Kvk=simpleq_Kv_Kvk(u,V,E,rho,Upsilon,k,taus,weights,N,J)
+
+ # denominator: (1-rho*\int (Kv)(2u-rho u*u))
+ denom=1-rhos[j]*integrate_f_chebyshev(s->1.,Kvk.*(2*u-rhos[j]*u.^2),k,taus,weights,N,J)
+
+ eta=rhos[j]*integrate_f_chebyshev(s->1.,Kvk.*u,k,taus,weights,N,J)/denom
+
+ @printf("% .15e % .15e\n",rhos[j],eta)
+ end
+end
+
+# Compute the two-point correlation function for simpleq using Kv
+function simpleq_Kv_2pt(minlrho,nlrho,taus,P,N,J,rho,a0,v,maxiter,tolerance,xmin,xmax,nx)
+ # init vectors
+ (weights,T,k,V,V0,A,Upsilon,Upsilon0)=anyeq_init(taus,P,N,J,v)
+
+ # compute initial guess from medeq
+ rhos=Array{Float64}(undef,nlrho)
+ for j in 0:nlrho-1
+ rhos[j+1]=(nlrho==1 ? rho : 10^(minlrho+(log10(rho)-minlrho)/(nlrho-1)*j))
+ end
+ u0s=anyeq_init_medeq(rhos,N,J,k,a0,v,maxiter,tolerance)
+ u0=u0s[nlrho]
+
+ (u,E,error)=anyeq_hatu(u0,P,N,J,rho,a0,weights,k,taus,V,V0,A,nothing,Upsilon,Upsilon0,v,maxiter,tolerance,Anyeq_approx(0.,0.,1.,0.,0.,0.,0.,0.,0.,0.,0.))
+
+ # Kv in Fourier space
+ Kvk=simpleq_Kv_Kvk(u,V,E,rho,Upsilon,k,taus,weights,N,J)
+
+ # denominator: (1-rho*\int (Kv)(2u-rho u*u))
+ denom=1-rho*integrate_f_chebyshev(s->1.,Kvk.*(2*u-rho*u.^2),k,taus,weights,N,J)
+
+ # Kv, u, u*Kv, u*u*Kv in real space
+ for i in 1:nx
+ x=xmin+(xmax-xmin)*i/nx
+ ux=inverse_fourier_chebyshev(u,x,k,taus,weights,N,J)
+ Kv=inverse_fourier_chebyshev(Kvk,x,k,taus,weights,N,J)
+ uKv=inverse_fourier_chebyshev(u.*Kvk,x,k,taus,weights,N,J)
+ uuKv=inverse_fourier_chebyshev(u.*u.*Kvk,x,k,taus,weights,N,J)
+
+ # correlation in real space
+ Cx=rho^2*((1-ux)-((1-ux)*Kv-2*rho*uKv+rho^2*uuKv)/denom)
+
+ @printf("% .15e % .15e\n",x,Cx)
+ end
+end
+
+# Kv
+function simpleq_Kv_Kvk(u,V,E,rho,Upsilon,k,taus,weights,N,J)
+ # (-Delta+v+4e(1-\rho u*)) in Fourier space
+ M=Array{Float64,2}(undef,N*J,N*J)
+ for zetapp in 0:J-1
+ for n in 1:N
+ M[:,zetapp*N+n]=conv_one_v_chebyshev(n,zetapp,Upsilon,k,taus,weights,N,J)
+ end
+ end
+ for i in 1:J*N
+ M[i,i]+=k[i]^2+4*E*(1-rho*u[i])
+ end
+
+ return inv(M)*V
+end
diff --git a/src/simpleq-hardcore.jl b/src/simpleq-hardcore.jl
new file mode 100644
index 0000000..ca64f78
--- /dev/null
+++ b/src/simpleq-hardcore.jl
@@ -0,0 +1,573 @@
+## Copyright 2021 Ian Jauslin
+##
+## 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.
+
+# compute energy as a function of rho
+function simpleq_hardcore_energy_rho(rhos,taus,P,N,J,maxiter,tolerance)
+ ## spawn workers
+ # number of workers
+ nw=nworkers()
+ # split jobs among workers
+ work=Array{Array{Int64,1},1}(undef,nw)
+ # init empty arrays
+ for p in 1:nw
+ work[p]=zeros(0)
+ end
+ for j in 1:length(rhos)
+ append!(work[j%nw+1],j)
+ end
+
+ # initialize vectors
+ (weights,weights_gL,r,T)=simpleq_hardcore_init(taus,P,N,J)
+
+ # initial guess
+ u0s=Array{Array{Float64}}(undef,length(rhos))
+ e0s=Array{Float64}(undef,length(rhos))
+ for j in 1:length(rhos)
+ u0s[j]=Array{Float64}(undef,N*J)
+ for i in 1:N*J
+ u0s[j][i]=1/(1+r[i]^2)^2
+ end
+ e0s[j]=pi*rhos[j]
+ end
+
+
+ # save result from each task
+ us=Array{Array{Float64}}(undef,length(rhos))
+ es=Array{Float64}(undef,length(rhos))
+ err=Array{Float64}(undef,length(rhos))
+
+ count=0
+ # for each worker
+ @sync for p in 1:nw
+ # for each task
+ @async for j in work[p]
+ count=count+1
+ if count>=nw
+ progress(count,length(rhos),10000)
+ end
+ # run the task
+ (us[j],es[j],err[j])=remotecall_fetch(simpleq_hardcore_hatu,workers()[p],u0s[j],e0s[j],rhos[j],r,taus,T,weights,weights_gL,P,N,J,maxiter,tolerance)
+ end
+ end
+
+ for j in 1:length(rhos)
+ @printf("% .15e % .15e % .15e\n",rhos[j],es[j],err[j])
+ end
+end
+
+# compute u(x)
+function simpleq_hardcore_ux(rho,taus,P,N,J,maxiter,tolerance)
+ # initialize vectors
+ (weights,weights_gL,r,T)=simpleq_hardcore_init(taus,P,N,J)
+
+ # initial guess
+ u0=Array{Float64}(undef,N*J)
+ for i in 1:N*J
+ u0[i]=1/(1+r[i]^2)^2
+ end
+ e0=pi*rho
+
+ (u,e,err)=simpleq_hardcore_hatu(u0,e0,rho,r,taus,T,weights,weights_gL,P,N,J,maxiter,tolerance)
+
+ for i in 1:N*J
+ @printf("% .15e % .15e\n",r[i],u[i])
+ end
+end
+
+# compute condensate fraction as a function of rho
+function simpleq_hardcore_condensate_fraction_rho(rhos,taus,P,N,J,maxiter,tolerance)
+ ## spawn workers
+ # number of workers
+ nw=nworkers()
+ # split jobs among workers
+ work=Array{Array{Int64,1},1}(undef,nw)
+ # init empty arrays
+ for p in 1:nw
+ work[p]=zeros(0)
+ end
+ for j in 1:length(rhos)
+ append!(work[j%nw+1],j)
+ end
+
+ # initialize vectors
+ (weights,weights_gL,r,T)=simpleq_hardcore_init(taus,P,N,J)
+
+ # initial guess
+ u0s=Array{Array{Float64}}(undef,length(rhos))
+ e0s=Array{Float64}(undef,length(rhos))
+ for j in 1:length(rhos)
+ u0s[j]=Array{Float64}(undef,N*J)
+ for i in 1:N*J
+ u0s[j][i]=1/(1+r[i]^2)^2
+ end
+ e0s[j]=pi*rhos[j]
+ end
+
+
+ # save result from each task
+ us=Array{Array{Float64}}(undef,length(rhos))
+ es=Array{Float64}(undef,length(rhos))
+ err=Array{Float64}(undef,length(rhos))
+
+ count=0
+ # for each worker
+ @sync for p in 1:nw
+ # for each task
+ @async for j in work[p]
+ count=count+1
+ if count>=nw
+ progress(count,length(rhos),10000)
+ end
+ # run the task
+ (us[j],es[j],err[j])=remotecall_fetch(simpleq_hardcore_hatu,workers()[p],u0s[j],e0s[j],rhos[j],r,taus,T,weights,weights_gL,P,N,J,maxiter,tolerance)
+ end
+ end
+
+ for j in 1:length(rhos)
+ du=-inv(simpleq_hardcore_DXi(us[j],es[j],rhos[j],r,taus,T,weights,weights_gL,P,N,J))*simpleq_hardcore_dXidmu(us[j],es[j],rhos[j],r,taus,T,weights,weights_gL,P,N,J)
+ @printf("% .15e % .15e % .15e\n",rhos[j],du[N*J+1],err[j])
+ end
+end
+
+
+# initialize computation
+@everywhere function simpleq_hardcore_init(taus,P,N,J)
+ # Gauss-Legendre weights
+ weights=gausslegendre(N)
+ weights_gL=gausslaguerre(N)
+
+ # r
+ r=Array{Float64}(undef,J*N)
+ for zeta in 0:J-1
+ for j in 1:N
+ xj=weights[1][j]
+ # set kj
+ r[zeta*N+j]=(2+(taus[zeta+2]-taus[zeta+1])*sin(pi*xj/2)-(taus[zeta+2]+taus[zeta+1]))/(2-(taus[zeta+2]-taus[zeta+1])*sin(pi*xj/2)+taus[zeta+2]+taus[zeta+1])
+ end
+ end
+
+ # Chebyshev polynomials
+ T=chebyshev_polynomials(P)
+
+ return (weights,weights_gL,r,T)
+end
+
+# compute u using chebyshev expansions
+@everywhere function simpleq_hardcore_hatu(u0,e0,rho,r,taus,T,weights,weights_gL,P,N,J,maxiter,tolerance)
+ # init
+ vec=Array{Float64}(undef,J*N+1)
+ for i in 1:J*N
+ vec[i]=u0[i]
+ end
+ vec[J*N+1]=e0
+
+ # quantify relative error
+ error=Inf
+
+ # run Newton algorithm
+ for i in 1:maxiter-1
+ u=vec[1:J*N]
+ e=vec[J*N+1]
+ new=vec-inv(simpleq_hardcore_DXi(u,e,rho,r,taus,T,weights,weights_gL,P,N,J))*simpleq_hardcore_Xi(u,e,rho,r,taus,T,weights,weights_gL,P,N,J)
+
+ error=norm(new-vec)/norm(new)
+ if(error<tolerance)
+ vec=new
+ break
+ end
+
+ vec=new
+ end
+
+ return(vec[1:J*N],vec[J*N+1],error)
+end
+
+# Xi
+@everywhere function simpleq_hardcore_Xi(u,e,rho,r,taus,T,weights,weights_gL,P,N,J)
+ out=Array{Float64}(undef,J*N+1)
+ FU=chebyshev(u,taus,weights,P,N,J,4)
+
+ #D's
+ d0=D0(e,rho,r,weights,N,J)
+ d1=D1(e,rho,r,taus,T,weights,weights_gL,P,N,J,4)
+ d2=D2(e,rho,r,taus,T,weights,weights_gL,P,N,J,4)
+
+ # u
+ for i in 1:J*N
+ out[i]=d0[i]+dot(FU,d1[i])+dot(FU,d2[i]*FU)-u[i]
+ end
+ # e
+ out[J*N+1]=-e+2*pi*rho*
+ ((1+2*sqrt(abs(e)))-gamma0(e,rho,weights)-dot(FU,gamma1(e,rho,taus,T,weights,weights_gL,P,J,4))-dot(FU,gamma2(e,rho,taus,T,weights,weights_gL,P,J,4)*FU))/
+ (1-8/3*pi*rho+rho^2*(gammabar0(weights)+dot(FU,gammabar1(taus,T,weights,P,J,4))+dot(FU,gammabar2(taus,T,weights,P,J,4)*FU)))
+
+ return out
+end
+# DXi
+@everywhere function simpleq_hardcore_DXi(u,e,rho,r,taus,T,weights,weights_gL,P,N,J)
+ out=Array{Float64,2}(undef,J*N+1,J*N+1)
+ FU=chebyshev(u,taus,weights,P,N,J,4)
+
+ #D's
+ d0=D0(e,rho,r,weights,N,J)
+ d1=D1(e,rho,r,taus,T,weights,weights_gL,P,N,J,4)
+ d2=D2(e,rho,r,taus,T,weights,weights_gL,P,N,J,4)
+ dsed0=dseD0(e,rho,r,weights,N,J)
+ dsed1=dseD1(e,rho,r,taus,T,weights,weights_gL,P,N,J,4)
+ dsed2=dseD2(e,rho,r,taus,T,weights,weights_gL,P,N,J,4)
+
+ # denominator of e
+ denom=1-8/3*pi*rho+rho^2*(gammabar0(weights)+dot(FU,gammabar1(taus,T,weights,P,J,4))+dot(FU,gammabar2(taus,T,weights,P,J,4)*FU))
+
+ for zetapp in 0:J-1
+ for n in 1:N
+ one=zeros(Int64,J*N)
+ one[zetapp*N+n]=1
+ Fone=chebyshev(one,taus,weights,P,N,J,4)
+
+ for i in 1:J*N
+ # du/du
+ out[i,zetapp*N+n]=dot(Fone,d1[i])+2*dot(FU,d2[i]*Fone)-(zetapp*N+n==i ? 1 : 0)
+ # du/de
+ out[i,J*N+1]=(dsed0[i]+dot(FU,dsed1[i])+dot(FU,dsed2[i]*FU))/(2*sqrt(abs(e)))*(e>=0 ? 1 : -1)
+ end
+ # de/du
+ out[J*N+1,zetapp*N+n]=2*pi*rho*
+ (-dot(Fone,gamma1(e,rho,taus,T,weights,weights_gL,P,J,4))-2*dot(FU,gamma2(e,rho,taus,T,weights,weights_gL,P,J,4)*Fone))/denom-
+ 2*pi*rho*
+ ((1+2*sqrt(abs(e)))-gamma0(e,rho,weights)-dot(FU,gamma1(e,rho,taus,T,weights,weights_gL,P,J,4))-dot(FU,gamma2(e,rho,taus,T,weights,weights_gL,P,J,4)*FU))*
+ rho^2*(dot(Fone,gammabar1(taus,T,weights,P,J,4))+2*dot(FU,gammabar2(taus,T,weights,P,J,4)*Fone))/denom^2
+ end
+ end
+ #de/de
+ out[J*N+1,J*N+1]=-1+2*pi*rho*
+ (2-dsedgamma0(e,rho,weights)-dot(FU,dsedgamma1(e,rho,taus,T,weights,weights_gL,P,J,4))-dot(FU,dsedgamma2(e,rho,taus,T,weights,weights_gL,P,J,4)*FU))/denom/
+ (2*sqrt(abs(e)))*(e>=0 ? 1 : -1)
+
+ return out
+end
+
+# dXi/dmu
+@everywhere function simpleq_hardcore_dXidmu(u,e,rho,r,taus,T,weights,weights_gL,P,N,J)
+ out=Array{Float64}(undef,J*N+1)
+ FU=chebyshev(u,taus,weights,P,N,J,4)
+
+ #D's
+ dsmud0=dsmuD0(e,rho,r,weights,N,J)
+ dsmud1=dsmuD1(e,rho,r,taus,T,weights,weights_gL,P,N,J,4)
+ dsmud2=dsmuD2(e,rho,r,taus,T,weights,weights_gL,P,N,J,4)
+
+ # u
+ for i in 1:J*N
+ out[i]=(dsmud0[i]+dot(FU,dsmud1[i])+dot(FU,dsmud2[i]*FU))/(4*sqrt(abs(e)))
+ end
+ # e
+ out[J*N+1]=2*pi*rho*(2/3+1/(2*sqrt(abs(e)))-
+ (dsmudgamma0(e,rho,weights)+dot(FU,dsmudgamma1(e,rho,taus,T,weights,weights_gL,P,J,4))+dot(FU,dsmudgamma2(e,rho,taus,T,weights,weights_gL,P,J,4)*FU))/(4*sqrt(abs(e)))
+ )/(1-8/3*pi*rho+rho^2*(gammabar0(weights)+dot(FU,gammabar1(taus,T,weights,P,J,4))+dot(FU,gammabar2(taus,T,weights,P,J,4)*FU)))
+
+ return out
+end
+
+# B's
+@everywhere function B0(r)
+ return pi/12*(r-1)^2*(r+5)
+end
+@everywhere function B1(r,zeta,n,taus,T,weights,nu)
+ return (taus[zeta+1]>=(2-r)/r || taus[zeta+2]<=-r/(r+2) ? 0 :
+ 8*pi/(r+1)*integrate_legendre(tau->
+ (1-(r-(1-tau)/(1+tau))^2)/(1+tau)^(3-nu)*T[n+1]((2*tau-(taus[zeta+1]+taus[zeta+2]))/(taus[zeta+2]-taus[zeta+1])),max(taus[zeta+1],-r/(r+2))
+ ,min(taus[zeta+2],(2-r)/r),weights)
+ )
+end
+@everywhere function B2(r,zeta,n,zetap,m,taus,T,weights,nu)
+ return 32*pi/(r+1)*integrate_legendre(tau->
+ 1/(1+tau)^(3-nu)*T[n+1]((2*tau-(taus[zeta+1]+taus[zeta+2]))/(taus[zeta+2]-taus[zeta+1]))*
+ (taus[zetap+1]>=alphap(abs(r-(1-tau)/(1+tau))-2*tau/(1+tau),tau) || taus[zetap+2]<=alpham(1+r,tau) ? 0 :
+ integrate_legendre(s->
+ 1/(1+s)^(3-nu)*T[m+1]((2*s-(taus[zetap+1]+taus[zetap+2]))/(taus[zetap+2]-taus[zetap+1])),max(taus[zetap+1]
+ ,alpham(1+r,tau)),min(taus[zetap+2],alphap(abs(r-(1-tau)/(1+tau))-2*tau/(1+tau),tau)),weights)
+ )
+ ,taus[zeta+1],taus[zeta+2],weights)
+end
+
+# D's
+@everywhere function D0(e,rho,r,weights,N,J)
+ out=Array{Float64}(undef,J*N)
+ for i in 1:J*N
+ out[i]=exp(-2*sqrt(abs(e))*r[i])/(r[i]+1)+
+ rho*sqrt(abs(e))/(r[i]+1)*integrate_legendre(s->
+ (s+1)*B0(s)*(exp(-2*sqrt(abs(e))*(r[i]-s))-exp(-2*sqrt(abs(e))*(r[i]+s)))/2
+ ,0,min(1,r[i]),weights)+
+ (r[i]>=1 ? 0 :
+ rho*sqrt(abs(e))/(2*(r[i]+1))*(1-exp(-4*sqrt(abs(e))*r[i]))*integrate_legendre(s->
+ (s+r[i]+1)*B0(s+r[i])*exp(-2*sqrt(abs(e))*s)
+ ,0,1-r[i],weights)
+ )
+ end
+ return out
+end
+@everywhere function D1(e,rho,r,taus,T,weights,weights_gL,P,N,J,nu)
+ out=Array{Array{Float64}}(undef,J*N)
+ for i in 1:J*N
+ out[i]=Array{Float64}(undef,(P+1)*J)
+ for zeta in 0:J-1
+ for n in 0:P
+ out[i][zeta*(P+1)+n+1]=rho*sqrt(abs(e))/(r[i]+1)*integrate_legendre(s->
+ (s+1)*B1(s,zeta,n,taus,T,weights,nu)*(exp(-2*sqrt(abs(e))*(r[i]-s))-exp(-2*sqrt(abs(e))*(r[i]+s)))/2
+ ,0,r[i],weights)+
+ rho*sqrt(abs(e))/(2*(r[i]+1))*(1-exp(-4*sqrt(abs(e))*r[i]))*integrate_laguerre(s->
+ (s+r[i]+1)*B1(s+r[i],zeta,n,taus,T,weights,nu)
+ ,2*sqrt(abs(e)),weights_gL)
+ end
+ end
+ end
+
+ return out
+end
+@everywhere function D2(e,rho,r,taus,T,weights,weights_gL,P,N,J,nu)
+ out=Array{Array{Float64,2}}(undef,J*N)
+ for i in 1:J*N
+ out[i]=Array{Float64,2}(undef,(P+1)*J,(P+1)*J)
+ for zeta in 0:J-1
+ for n in 0:P
+ for zetap in 0:J-1
+ for m in 0:P
+ out[i][zeta*(P+1)+n+1,zetap*(P+1)+m+1]=rho*sqrt(abs(e))/(r[i]+1)*integrate_legendre(s->
+ (s+1)*B2(s,zeta,n,zetap,m,taus,T,weights,nu)*(exp(-2*sqrt(abs(e))*(r[i]-s))-exp(-2*sqrt(abs(e))*(r[i]+s)))/2
+ ,0,r[i],weights)+
+ rho*sqrt(abs(e))/(2*(r[i]+1))*(1-exp(-4*sqrt(abs(e))*r[i]))*integrate_laguerre(s->
+ (s+r[i]+1)*B2(s+r[i],zeta,n,zetap,m,taus,T,weights,nu)
+ ,2*sqrt(abs(e)),weights_gL)
+ end
+ end
+ end
+ end
+ end
+ return out
+end
+
+# dD/d sqrt(abs(e))'s
+@everywhere function dseD0(e,rho,r,weights,N,J)
+ out=Array{Float64}(undef,J*N)
+ for i in 1:J*N
+ out[i]=-2*r[i]*exp(-2*sqrt(abs(e))*r[i])/(r[i]+1)+
+ rho/(r[i]+1)*integrate_legendre(s->
+ (s+1)*B0(s)*((1-2*sqrt(abs(e))*r[i])*(exp(-2*sqrt(abs(e))*(r[i]-s))-exp(-2*sqrt(abs(e))*(r[i]+s)))/2+2*sqrt(abs(e))*s*(exp(-2*sqrt(abs(e))*(r[i]-s))+exp(-2*sqrt(abs(e))*(r[i]+s)))/2)
+ ,0,min(1,r[i]),weights)+
+ (r[i]>=1 ? 0 :
+ rho/(2*(r[i]+1))*integrate_legendre(s->(s+r[i]+1)*B0(s+r[i])*((1-2*sqrt(abs(e))*s)*(1-exp(-4*sqrt(abs(e))*r[i]))*exp(-2*sqrt(abs(e))*s)+4*sqrt(abs(e))*r[i]*exp(-2*sqrt(abs(e))*(2*r[i]+s))),0,1-r[i],weights)
+ )
+ end
+ return out
+end
+@everywhere function dseD1(e,rho,r,taus,T,weights,weights_gL,P,N,J,nu)
+ out=Array{Array{Float64}}(undef,J*N)
+ for i in 1:J*N
+ out[i]=Array{Float64}(undef,(P+1)*J)
+ for zeta in 0:J-1
+ for n in 0:P
+ out[i][zeta*(P+1)+n+1]=rho/(r[i]+1)*integrate_legendre(s->
+ (s+1)*B1(s,zeta,n,taus,T,weights,nu)*((1-2*sqrt(abs(e))*r[i])*(exp(-2*sqrt(abs(e))*(r[i]-s))-exp(-2*sqrt(abs(e))*(r[i]+s)))/2+2*sqrt(abs(e))*s*(exp(-2*sqrt(abs(e))*(r[i]-s))+exp(-2*sqrt(abs(e))*(r[i]+s)))/2)
+ ,0,r[i],weights)+
+ rho/(2*(r[i]+1))*integrate_laguerre(s->
+ (s+r[i]+1)*B1(s+r[i],zeta,n,taus,T,weights,nu)*((1-2*sqrt(abs(e))*s)*(1-exp(-4*sqrt(abs(e))*r[i]))+4*sqrt(abs(e))*r[i]*exp(-4*sqrt(abs(e))*r[i]))
+ ,2*sqrt(abs(e)),weights_gL)
+ end
+ end
+ end
+ return out
+end
+@everywhere function dseD2(e,rho,r,taus,T,weights,weights_gL,P,N,J,nu)
+ out=Array{Array{Float64,2}}(undef,J*N)
+ for i in 1:J*N
+ out[i]=Array{Float64,2}(undef,(P+1)*J,(P+1)*J)
+ for zeta in 0:J-1
+ for n in 0:P
+ for zetap in 0:J-1
+ for m in 0:P
+ out[i][zeta*(P+1)+n+1,zetap*(P+1)+m+1]=rho/(r[i]+1)*integrate_legendre(s->
+ (s+1)*B2(s,zeta,n,zetap,m,taus,T,weights,nu)*((1-2*sqrt(abs(e))*r[i])*(exp(-2*sqrt(abs(e))*(r[i]-s))-exp(-2*sqrt(abs(e))*(r[i]+s)))/2+2*sqrt(abs(e))*s*(exp(-2*sqrt(abs(e))*(r[i]-s))+exp(-2*sqrt(abs(e))*(r[i]+s)))/2)
+ ,0,r[i],weights)+
+ rho/(2*(r[i]+1))*integrate_laguerre(s->
+ (s+r[i]+1)*B2(s+r[i],zeta,n,zetap,m,taus,T,weights,nu)*((1-2*sqrt(abs(e))*s)*(1-exp(-4*sqrt(abs(e))*r[i]))+4*sqrt(abs(e))*r[i]*exp(-4*sqrt(abs(e))*r[i]))
+ ,2*sqrt(abs(e)),weights_gL)
+ end
+ end
+ end
+ end
+ end
+ return out
+end
+
+# dD/d sqrt(abs(e+mu/2))'s
+@everywhere function dsmuD0(e,rho,r,weights,N,J)
+ out=Array{Float64}(undef,J*N)
+ for i in 1:J*N
+ out[i]=-2*r[i]*exp(-2*sqrt(abs(e))*r[i])/(r[i]+1)+
+ rho/(r[i]+1)*integrate_legendre(s->
+ (s+1)*B0(s)*((-1-2*sqrt(abs(e))*r[i])*(exp(-2*sqrt(abs(e))*(r[i]-s))-exp(-2*sqrt(abs(e))*(r[i]+s)))/2+2*sqrt(abs(e))*s*(exp(-2*sqrt(abs(e))*(r[i]-s))+exp(-2*sqrt(abs(e))*(r[i]+s)))/2)
+ ,0,min(1,r[i]),weights)+
+ (r[i]>=1 ? 0 :
+ rho/(2*(r[i]+1))*integrate_legendre(s->(s+r[i]+1)*B0(s+r[i])*((-1-2*sqrt(abs(e))*s)*(1-exp(-4*sqrt(abs(e))*r[i]))*exp(-2*sqrt(abs(e))*s)+4*sqrt(abs(e))*r[i]*exp(-2*sqrt(abs(e))*(2*r[i]+s))),0,1-r[i],weights)
+ )
+ end
+ return out
+end
+@everywhere function dsmuD1(e,rho,r,taus,T,weights,weights_gL,P,N,J,nu)
+ out=Array{Array{Float64}}(undef,J*N)
+ for i in 1:J*N
+ out[i]=Array{Float64}(undef,(P+1)*J)
+ for zeta in 0:J-1
+ for n in 0:P
+ out[i][zeta*(P+1)+n+1]=rho/(r[i]+1)*integrate_legendre(s->
+ (s+1)*B1(s,zeta,n,taus,T,weights,nu)*((-1-2*sqrt(abs(e))*r[i])*(exp(-2*sqrt(abs(e))*(r[i]-s))-exp(-2*sqrt(abs(e))*(r[i]+s)))/2+2*sqrt(abs(e))*s*(exp(-2*sqrt(abs(e))*(r[i]-s))+exp(-2*sqrt(abs(e))*(r[i]+s)))/2)
+ ,0,r[i],weights)+
+ rho/(2*(r[i]+1))*integrate_laguerre(s->
+ (s+r[i]+1)*B1(s+r[i],zeta,n,taus,T,weights,nu)*((-1-2*sqrt(abs(e))*s)*(1-exp(-4*sqrt(abs(e))*r[i]))+4*sqrt(abs(e))*r[i]*exp(-4*sqrt(abs(e))*r[i]))
+ ,2*sqrt(abs(e)),weights_gL)
+ end
+ end
+ end
+ return out
+end
+@everywhere function dsmuD2(e,rho,r,taus,T,weights,weights_gL,P,N,J,nu)
+ out=Array{Array{Float64,2}}(undef,J*N)
+ for i in 1:J*N
+ out[i]=Array{Float64,2}(undef,(P+1)*J,(P+1)*J)
+ for zeta in 0:J-1
+ for n in 0:P
+ for zetap in 0:J-1
+ for m in 0:P
+ out[i][zeta*(P+1)+n+1,zetap*(P+1)+m+1]=rho/(r[i]+1)*integrate_legendre(s->
+ (s+1)*B2(s,zeta,n,zetap,m,taus,T,weights,nu)*((-1-2*sqrt(abs(e))*r[i])*(exp(-2*sqrt(abs(e))*(r[i]-s))-exp(-2*sqrt(abs(e))*(r[i]+s)))/2+2*sqrt(abs(e))*s*(exp(-2*sqrt(abs(e))*(r[i]-s))+exp(-2*sqrt(abs(e))*(r[i]+s)))/2)
+ ,0,r[i],weights)+
+ rho/(2*(r[i]+1))*integrate_laguerre(s->
+ (s+r[i]+1)*B2(s+r[i],zeta,n,zetap,m,taus,T,weights,nu)*((-1-2*sqrt(abs(e))*s)*(1-exp(-4*sqrt(abs(e))*r[i]))+4*sqrt(abs(e))*r[i]*exp(-4*sqrt(abs(e))*r[i]))
+ ,2*sqrt(abs(e)),weights_gL)
+ end
+ end
+ end
+ end
+ end
+ return out
+end
+
+# gamma's
+@everywhere function gamma0(e,rho,weights)
+ return 2*rho*e*integrate_legendre(s->(s+1)*B0(s)*exp(-2*sqrt(abs(e))*s),0,1,weights)
+end
+@everywhere function gamma1(e,rho,taus,T,weights,weights_gL,P,J,nu)
+ out=Array{Float64}(undef,J*(P+1))
+ for zeta in 0:J-1
+ for n in 0:P
+ out[zeta*(P+1)+n+1]=2*rho*e*integrate_laguerre(s->(s+1)*B1(s,zeta,n,taus,T,weights,nu),2*sqrt(abs(e)),weights_gL)
+ end
+ end
+ return out
+end
+@everywhere function gamma2(e,rho,taus,T,weights,weights_gL,P,J,nu)
+ out=Array{Float64,2}(undef,J*(P+1),J*(P+1))
+ for zeta in 0:J-1
+ for n in 0:P
+ for zetap in 0:J-1
+ for m in 0:P
+ out[zeta*(P+1)+n+1,zetap*(P+1)+m+1]=2*rho*e*integrate_laguerre(s->(s+1)*B2(s,zeta,n,zetap,m,taus,T,weights,nu),2*sqrt(abs(e)),weights_gL)
+ end
+ end
+ end
+ end
+ return out
+end
+
+# dgamma/d sqrt(abs(e))'s
+@everywhere function dsedgamma0(e,rho,weights)
+ return 4*rho*sqrt(abs(e))*integrate_legendre(s->(s+1)*B0(s)*(1-sqrt(abs(e))*s)*exp(-2*sqrt(abs(e))*s),0,1,weights)
+end
+@everywhere function dsedgamma1(e,rho,taus,T,weights,weights_gL,P,J,nu)
+ out=Array{Float64}(undef,J*(P+1))
+ for zeta in 0:J-1
+ for n in 0:P
+ out[zeta*(P+1)+n+1]=4*rho*e*integrate_laguerre(s->(s+1)*B1(s,zeta,n,taus,T,weights,nu)*(1-sqrt(abs(e))*s),2*sqrt(abs(e)),weights_gL)
+ end
+ end
+ return out
+end
+@everywhere function dsedgamma2(e,rho,taus,T,weights,weights_gL,P,J,nu)
+ out=Array{Float64,2}(undef,J*(P+1),J*(P+1))
+ for zeta in 0:J-1
+ for n in 0:P
+ for zetap in 0:J-1
+ for m in 0:P
+ out[zeta*(P+1)+n+1,zetap*(P+1)+m+1]=4*rho*e*integrate_laguerre(s->(s+1)*B2(s,zeta,n,zetap,m,taus,T,weights,nu)*(1-sqrt(abs(e))*s),2*sqrt(abs(e)),weights_gL)
+ end
+ end
+ end
+ end
+ return out
+end
+
+# dgamma/d sqrt(e+mu/2)'s
+@everywhere function dsmudgamma0(e,rho,weights)
+ return -4*rho*e*integrate_legendre(s->(s+1)*s*B0(s)*exp(-2*sqrt(abs(e))*s),0,1,weights)
+end
+@everywhere function dsmudgamma1(e,rho,taus,T,weights,weights_gL,P,J,nu)
+ out=Array{Float64}(undef,J*(P+1))
+ for zeta in 0:J-1
+ for n in 0:P
+ out[zeta*(P+1)+n+1]=-4*rho*e*integrate_laguerre(s->s*(s+1)*B1(s,zeta,n,taus,T,weights,nu),2*sqrt(abs(e)),weights_gL)
+ end
+ end
+ return out
+end
+@everywhere function dsmudgamma2(e,rho,taus,T,weights,weights_gL,P,J,nu)
+ out=Array{Float64,2}(undef,J*(P+1),J*(P+1))
+ for zeta in 0:J-1
+ for n in 0:P
+ for zetap in 0:J-1
+ for m in 0:P
+ out[zeta*(P+1)+n+1,zetap*(P+1)+m+1]=-4*rho*e*integrate_laguerre(s->s*(s+1)*B2(s,zeta,n,zetap,m,taus,T,weights,nu),2*sqrt(abs(e)),weights_gL)
+ end
+ end
+ end
+ end
+ return out
+end
+
+# \bar gamma's
+@everywhere function gammabar0(weights)
+ return 4*pi*integrate_legendre(s->s^2*B0(s-1),0,1,weights)
+end
+@everywhere function gammabar1(taus,T,weights,P,J,nu)
+ out=Array{Float64}(undef,J*(P+1))
+ for zeta in 0:J-1
+ for n in 0:P
+ out[zeta*(P+1)+n+1]=4*pi*integrate_legendre(s->s^2*B1(s-1,zeta,n,taus,T,weights,nu),0,1,weights)
+ end
+ end
+ return out
+end
+@everywhere function gammabar2(taus,T,weights,P,J,nu)
+ out=Array{Float64,2}(undef,J*(P+1),J*(P+1))
+ for zeta in 0:J-1
+ for n in 0:P
+ for zetap in 0:J-1
+ for m in 0:P
+ out[zeta*(P+1)+n+1,zetap*(P+1)+m+1]=4*pi*integrate_legendre(s->s^2*B2(s-1,zeta,n,zetap,m,taus,T,weights,nu),0,1,weights)
+ end
+ end
+ end
+ end
+ return out
+end
diff --git a/src/simpleq-iteration.jl b/src/simpleq-iteration.jl
new file mode 100644
index 0000000..98977b8
--- /dev/null
+++ b/src/simpleq-iteration.jl
@@ -0,0 +1,94 @@
+## Copyright 2021 Ian Jauslin
+##
+## 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.
+
+# compute rho(e) using the iteration
+function simpleq_iteration_rho_e(es,order,v,maxiter)
+ for j in 1:length(es)
+ (u,rho)=simpleq_iteration_hatun(es[j],order,v,maxiter)
+ @printf("% .15e % .15e\n",es[j],real(rho[maxiter+1]))
+ end
+end
+
+# compute u(x) using the iteration and print at every step
+function simpleq_iteration_ux(order,e,v,maxiter,xmin,xmax,nx)
+ (u,rho)=simpleq_iteration_hatun(e,order,v,maxiter)
+
+ weights=gausslegendre(order)
+ for i in 1:nx
+ x=xmin+(xmax-xmin)*i/nx
+ @printf("% .15e ",x)
+ for n in 2:maxiter+1
+ @printf("% .15e ",real(easyeq_u_x(x,u[n],weights)))
+ end
+ print('\n')
+ end
+end
+
+
+# \hat u_n
+function simpleq_iteration_hatun(e,order,v,maxiter)
+ # gauss legendre weights
+ weights=gausslegendre(order)
+
+ # initialize V and Eta
+ (V,V0)=easyeq_init_v(weights,v)
+ (Eta,Eta0)=easyeq_init_H(weights,v)
+
+ # init u and rho
+ u=Array{Array{Float64}}(undef,maxiter+1)
+ u[1]=zeros(Float64,order)
+ rho=zeros(Float64,maxiter+1)
+
+ # iterate
+ for n in 1:maxiter
+ u[n+1]=simpleq_iteration_A(e,weights,Eta)\simpleq_iteration_b(u[n],e,rho[n],V)
+ rho[n+1]=simpleq_iteration_rhon(u[n+1],e,weights,V0,Eta0)
+ end
+
+ return (u,rho)
+end
+
+# A
+function simpleq_iteration_A(e,weights,Eta)
+ N=length(weights[1])
+ out=zeros(Float64,N,N)
+ for i in 1:N
+ k=(1-weights[1][i])/(1+weights[1][i])
+ out[i,i]=k^2+4*e
+ for j in 1:N
+ y=(weights[1][j]+1)/2
+ out[i,j]+=weights[2][j]*(1-y)*Eta[i][j]/(2*(2*pi)^3*y^3)
+ end
+ end
+ return out
+end
+
+# b
+function simpleq_iteration_b(u,e,rho,V)
+ out=zeros(Float64,length(V))
+ for i in 1:length(V)
+ out[i]=V[i]+2*e*rho*u[i]^2
+ end
+ return out
+end
+
+# rho_n
+function simpleq_iteration_rhon(u,e,weights,V0,Eta0)
+ S=V0
+ for i in 1:length(weights[1])
+ y=(weights[1][i]+1)/2
+ S+=-weights[2][i]*(1-y)*u[i]*Eta0[i]/(2*(2*pi)^3*y^3)
+ end
+ return 2*e/S
+end
diff --git a/src/tools.jl b/src/tools.jl
new file mode 100644
index 0000000..0d3dc7f
--- /dev/null
+++ b/src/tools.jl
@@ -0,0 +1,49 @@
+## Copyright 2021 Ian Jauslin
+##
+## 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.
+
+# \Phi(x)=2*(1-sqrt(1-x))/x
+@everywhere function Phi(x)
+ if abs(x)>1e-5
+ return 2*(1-sqrt(abs(1-x)))/x
+ else
+ return 1+x/4+x^2/8+5*x^3/64+7*x^4/128+21*x^5/512
+ end
+end
+# \partial\Phi
+@everywhere function dPhi(x)
+ #if abs(x-1)<1e-5
+ # @printf(stderr,"warning: dPhi is singular at 1, and evaluating it at (% .8e+i% .8e)\n",real(x),imag(x))
+ #end
+ if abs(x)>1e-5
+ return 1/(sqrt(abs(1-x))*x)*(1-x>=0 ? 1 : -1)-2*(1-sqrt(abs(1-x)))/x^2
+ else
+ return 1/4+x/4+15*x^2/64+7*x^3/32+105*x^4/512+99*x^5/512
+ end
+end
+
+# apply Phi to every element of a vector
+@everywhere function dotPhi(v)
+ out=zeros(Float64,length(v))
+ for i in 1:length(v)
+ out[i]=Phi(v[i])
+ end
+ return out
+end
+@everywhere function dotdPhi(v)
+ out=zeros(Float64,length(v))
+ for i in 1:length(v)
+ out[i]=dPhi(v[i])
+ end
+ return out
+end