diff --git a/doc/Makefile b/doc/Makefile index d4bb2cbb..d0c3cbf1 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -5,8 +5,8 @@ # from the environment for the first two. SPHINXOPTS ?= SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = _build +SOURCEDIR = source +BUILDDIR = build # Put it first so that "make" without argument is like "make help". help: diff --git a/doc/check_names.py b/doc/check_names.py deleted file mode 100644 index 6a6db356..00000000 --- a/doc/check_names.py +++ /dev/null @@ -1,45 +0,0 @@ -# Generate the routines divide by slicot-chapters for sphinx-doc. -# Only prints out the names, copy & past them into slycot_outer.rst and slycot_inner.rst. -import re -import pandas as pd -import warnings - -import slycot -slycot.__version__ - -def get_slycot_routines(sly): - all_attributes = dir(sly) - r = re.compile("[a-z][a-z][0-9][0-9a-z][a-z][a-z]") - matched_attributes = list(filter(r.match, all_attributes)) - return matched_attributes - -def get_slycot_routines_help(file,pre=""): - textfile = open(file, 'r') - filetext = textfile.read() - textfile.close() - lines = filetext.split("\n") - res = [ele.replace(" ","") for ele in lines] - res = [ele.replace("_wrapper.","") for ele in res] - - r = re.compile("[a-z][a-z][0-9][0-9a-z][a-z][a-z]") - matched_attributes = list(filter(r.match, res)) - return matched_attributes - -slycot_wrapper = get_slycot_routines(slycot) -slycot_wrapper.sort() -slycot_f2py_wrapper = get_slycot_routines(slycot._wrapper) -slycot_f2py_wrapper.sort() - -slycot_wrapper_help = get_slycot_routines_help("source/reference/slycot_outer.rst") -slycot_wrapper_help.sort() - -slycot_f2py_wrapper_help = get_slycot_routines_help("source/reference/slycot_inner.rst") -slycot_f2py_wrapper_help.sort() - -missing = list(set(slycot_wrapper) - set(slycot_wrapper_help)) -if bool(missing): - warnings.warn(f"The routines {missing} are missing in 'slycot_outer.rst'.") - -missing = list(set(slycot_f2py_wrapper) - set(slycot_f2py_wrapper_help)) -if bool(missing): - warnings.warn(f"The routines _wrapper.{missing} are missing in 'slycot_inner.rst'.") \ No newline at end of file diff --git a/doc/create_names_for_reference.py b/doc/create_names_for_reference.py deleted file mode 100644 index 39117918..00000000 --- a/doc/create_names_for_reference.py +++ /dev/null @@ -1,37 +0,0 @@ -# Generate the routines divide by slicot-chapters for sphinx-doc. -# Only prints out the names, copy & past them into slycot_outer.rst and slycot_inner.rst. -import re -import pandas as pd -import matplotlib.pyplot as plt -from matplotlib_venn import venn2 - -import slycot -slycot.__version__ - -def get_slycot_routines(sly): - all_attributes = dir(sly) - r = re.compile("[a-z][a-z][0-9][0-9a-z][a-z][a-z]") - matched_attributes = list(filter(r.match, all_attributes)) - return matched_attributes - -slycot_wrapper = get_slycot_routines(slycot) -slycot_wrapper.sort() -slycot_f2py_wrapper = get_slycot_routines(slycot._wrapper) -slycot_f2py_wrapper.sort() - -from itertools import groupby -from operator import itemgetter - -print(f"\nslycot_wrapper {len(slycot_wrapper)}\n") -for chapter_letter, chapter_routines in groupby(sorted(slycot_wrapper), key=itemgetter(0)): - print(chapter_letter) - for routine in chapter_routines: - print(routine) - print("\n") - -print(f"\nslycot_f2py_wrapper {len(slycot_f2py_wrapper)}\n") -for chapter_letter, chapter_routines in groupby(sorted(slycot_f2py_wrapper), key=itemgetter(0)): - print(chapter_letter) - for routine in chapter_routines: - print("_wrapper."+routine) - print("\n") diff --git a/doc/make.bat b/doc/make.bat old mode 100755 new mode 100644 index 32bb2452..747ffb7b --- a/doc/make.bat +++ b/doc/make.bat @@ -7,8 +7,8 @@ REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) -set SOURCEDIR=. -set BUILDDIR=_build +set SOURCEDIR=source +set BUILDDIR=build %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( diff --git a/doc/conf.py b/doc/source/conf.py similarity index 96% rename from doc/conf.py rename to doc/source/conf.py index c9ad4035..3c1eb275 100644 --- a/doc/conf.py +++ b/doc/source/conf.py @@ -5,14 +5,11 @@ # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information - import os import sys sys.path.insert(0, os.path.abspath('../slycot')) -import subprocess -subprocess.run(["python", "check_names.py"]) - +master_doc = "index" from datetime import date project = 'Slycot' copyright = f'{date.today().year}, Slycot Developers' @@ -29,7 +26,6 @@ print("version %s, release %s" % (version, release)) - # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/doc/source/dev/contributing.rst b/doc/source/contributing/index.rst similarity index 78% rename from doc/source/dev/contributing.rst rename to doc/source/contributing/index.rst index d7b97152..e1ccbbf0 100644 --- a/doc/source/dev/contributing.rst +++ b/doc/source/contributing/index.rst @@ -1,10 +1,12 @@ -********************** -Contributing to Slycot -********************** +.. this page is referenced from the front page but it's unnecessary as a navigation section for now. + +:orphan: +Contributing to Slycot +====================== Development process and tools -============================= +----------------------------- The development process is currently described on the `slycot github repo `_ and the `slycot github wiki `_. You should be familiar with following topics: @@ -17,13 +19,12 @@ You should be familiar with following topics: - `f2py `_ numpydoc -======== +-------- Slycot uses numpydoc for the docstring style in order to provide support the Numpy docstring format in sphinx, `see numpydoc example `_. F2PY -==== +---- -Slycot heavily relias on `F2PY `_. -`F2PY`_ is currently a part of `NumPy `_. \ No newline at end of file +Slycot heavily relias on `F2PY `_, which is currently a part of `NumPy `_. \ No newline at end of file diff --git a/doc/source/dev/index.rst b/doc/source/dev/index.rst deleted file mode 100644 index 21cfebb4..00000000 --- a/doc/source/dev/index.rst +++ /dev/null @@ -1,10 +0,0 @@ -****************** -Development -****************** - -.. toctree:: - :maxdepth: 1 - - contributing - inspect_slycot - inspect_slicot_slycot diff --git a/doc/source/examples/ab13dd_nb.ipynb b/doc/source/examples/ab13dd_nb.ipynb deleted file mode 120000 index 255c0e77..00000000 --- a/doc/source/examples/ab13dd_nb.ipynb +++ /dev/null @@ -1 +0,0 @@ -../../../examples/ab13dd_nb.ipynb \ No newline at end of file diff --git a/doc/source/examples/ad13dd_example.rst b/doc/source/examples/ad13dd_example.rst deleted file mode 100644 index 53f05964..00000000 --- a/doc/source/examples/ad13dd_example.rst +++ /dev/null @@ -1,10 +0,0 @@ -************** -ad13dd_example -************** - -Code -==== - -.. literalinclude:: ../../../examples/ab13dd_example.py - :language: python - :linenos: \ No newline at end of file diff --git a/doc/source/examples/index.rst b/doc/source/examples/index.rst deleted file mode 100644 index 59877bd8..00000000 --- a/doc/source/examples/index.rst +++ /dev/null @@ -1,21 +0,0 @@ -******** -Examples -******** - - -Python scripts -============== - -.. toctree:: - :maxdepth: 1 - - ad13dd_example - - -Jupyter notebooks -================= - -.. toctree:: - :maxdepth: 1 - - ab13dd_nb \ No newline at end of file diff --git a/doc/source/explanation/index.rst b/doc/source/explanation/index.rst new file mode 100644 index 00000000..dec31068 --- /dev/null +++ b/doc/source/explanation/index.rst @@ -0,0 +1,12 @@ +.. this page is referenced from the front page but it's unnecessary as a navigation section for now. + +:orphan: + +Inspect +======= + +.. toctree:: + :maxdepth: 1 + + inspect_slycot + inspect_slicot_slycot diff --git a/doc/source/dev/inspect_slicot_slycot.ipynb b/doc/source/explanation/inspect_slicot_slycot.ipynb similarity index 100% rename from doc/source/dev/inspect_slicot_slycot.ipynb rename to doc/source/explanation/inspect_slicot_slycot.ipynb diff --git a/doc/source/dev/inspect_slycot.ipynb b/doc/source/explanation/inspect_slycot.ipynb similarity index 100% rename from doc/source/dev/inspect_slycot.ipynb rename to doc/source/explanation/inspect_slycot.ipynb diff --git a/doc/source/dev/slicot_routines.txt b/doc/source/explanation/slicot_routines.txt similarity index 100% rename from doc/source/dev/slicot_routines.txt rename to doc/source/explanation/slicot_routines.txt diff --git a/doc/source/guides/ab13dd_nb.ipynb b/doc/source/guides/ab13dd_nb.ipynb new file mode 100644 index 00000000..84af663b --- /dev/null +++ b/doc/source/guides/ab13dd_nb.ipynb @@ -0,0 +1,200 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# ab13dd Example\n", + "\n", + "Johannes Kaisinger, 26 July 2023" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import scipy.linalg as linalg\n", + "import slycot" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "A = np.array([\n", + " [-1, 10],\n", + " [0, -1]\n", + "])\n", + "\n", + "B = np.array([\n", + " [0],\n", + " [1]])\n", + "\n", + "C = np.array([\n", + " [1, 0]])\n", + "D = np.zeros((1,1))\n", + "\n", + "n, m = B.shape\n", + "p, _ = C.shape" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Slycot H-infinity Norm" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10.0\n" + ] + } + ], + "source": [ + "out = slycot.ab13dd('C', 'I', 'N', 'D', n, m, p, A, np.eye(n), B, C, D)\n", + "norm_sylcot, _ = out\n", + "print(norm_sylcot)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Bisection algorithm H-infinity Norm" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "def H_inf(A,B,C,D,gam_l,gam_h,emin):\n", + " \"\"\"naive implementation of bisection algorithm for H-infinity norm\n", + "\n", + " Args:\n", + " A (_type_): _description_\n", + " B (_type_): _description_\n", + " C (_type_): _description_\n", + " D (_type_): _description_\n", + " gam_l (_type_): _description_\n", + " gam_h (_type_): _description_\n", + " emin (_type_): _description_\n", + "\n", + " Returns:\n", + " _type_: _description_\n", + " \"\"\"\n", + " gam_last_stable = None\n", + " while (gam_h - gam_l) > emin:\n", + " gam = (gam_l+gam_h)/2\n", + " R = gam**2*np.eye(1)-D.T@D\n", + " R_inv = linalg.inv(R)\n", + " Mgam = np.vstack((\n", + " np.hstack((A+B@R_inv@D.T@C, B@R_inv@B.T)),\n", + " np.hstack((-C.T@(np.eye(1)+D@R_inv@D.T)@C, -(A+B@R_inv@D.T@C).T))))\n", + " d = linalg.eigvals(Mgam)\n", + " if np.any(np.imag(d)):\n", + " gam_l = gam\n", + " else:\n", + " gam_h = gam\n", + " gam_last_stable = gam\n", + " return gam_last_stable" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10.000000000000638\n" + ] + } + ], + "source": [ + "norm_bi = H_inf(A,B,C,D,0.001,100,1e-10)\n", + "print(norm_bi)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Compare" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10.0\n", + "10.000000000000638\n" + ] + }, + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# compare results\n", + "print(norm_sylcot)\n", + "print(norm_bi)\n", + "np.allclose(norm_sylcot,norm_bi)\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "slycot-dev", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/doc/source/guides/system_norms.rst b/doc/source/guides/system_norms.rst new file mode 100644 index 00000000..01126619 --- /dev/null +++ b/doc/source/guides/system_norms.rst @@ -0,0 +1,11 @@ +.. this page is referenced from the front page but it's unnecessary as a navigation section for now. + +:orphan: + +System norms +============ + +.. toctree:: + :maxdepth: 1 + + ab13dd_nb \ No newline at end of file diff --git a/doc/index.rst b/doc/source/index.rst similarity index 52% rename from doc/index.rst rename to doc/source/index.rst index 28579d4d..47736c24 100644 --- a/doc/index.rst +++ b/doc/source/index.rst @@ -1,15 +1,16 @@ -.. slycot documentation master file, created by - sphinx-quickstart on Wed Jul 26 15:18:00 2023. +.. Slycot documentation master file, created by + sphinx-quickstart on Thu Jan 18 21:43:47 2024. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Slycot -====== +Welcome to Slycot's documentation! +================================== Python wrapper for selected `SLICOT `_ routines, notably including solvers for Riccati, Lyapunov, and Sylvester equations. -.. rubric:: Chapters +Chapters +-------- The Slycot library is organised by chapters. Each chapter can be identified by a single letter. The following chapters are included: @@ -25,19 +26,38 @@ The Slycot library is organised by chapters. Each chapter can be identified by a - ``T`` : Transformation Routines - ``U`` : Utility Routines -.. rubric:: Documentation +.. toctree:: + :maxdepth: 2 + :hidden: + :caption: 🚀 Tutorials + + /tutorial/index + /tutorial/getting + +.. toctree:: + :maxdepth: 2 + :hidden: + :caption: 💡 Explanation + + /explanation/index .. toctree:: - :maxdepth: 1 + :maxdepth: 2 + :hidden: + :caption: 🪄 How-to guides - intro - source/reference/index - source/dev/index - source/examples/index + /guides/system_norms -Indices and tables -================== +.. toctree:: + :maxdepth: 2 + :hidden: + :caption: 📚 Reference + + /reference/index + +.. toctree:: + :maxdepth: 2 + :hidden: + :caption: Contributing -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` + /contributing/index diff --git a/doc/source/reference/index.rst b/doc/source/reference/index.rst index 4a0ea8a5..ee1de2dd 100644 --- a/doc/source/reference/index.rst +++ b/doc/source/reference/index.rst @@ -1,6 +1,9 @@ -**************** -Slycot reference -**************** +.. this page is referenced from the front page but it's unnecessary as a navigation section for now. + +:orphan: + +Reference +========= For most users only the :ref:`function-ref` is important. @@ -8,10 +11,16 @@ For most users only the :ref:`function-ref` is important. :maxdepth: 1 slycot_outer + +For advanced users and developer also the + +.. toctree:: + :maxdepth: 1 + slycot_inner -For advanced users and developer also the :ref:`inner_function-ref` and the +and the `SLICOT-Reference `_ -can be important. +can be important. \ No newline at end of file diff --git a/doc/source/tutorial/getting.rst b/doc/source/tutorial/getting.rst new file mode 100644 index 00000000..4beee7be --- /dev/null +++ b/doc/source/tutorial/getting.rst @@ -0,0 +1,7 @@ +Getting started +=============== + +There are two different ways to use the package. For the default interface +described in :ref:`function-ref`, simply import the slycot package as follows:: + + >>> import slycot \ No newline at end of file diff --git a/doc/intro.rst b/doc/source/tutorial/index.rst similarity index 66% rename from doc/intro.rst rename to doc/source/tutorial/index.rst index f92429a0..b0df32b6 100644 --- a/doc/intro.rst +++ b/doc/source/tutorial/index.rst @@ -1,10 +1,6 @@ -************ -Introduction -************ +.. this page is referenced from the front page but it's unnecessary as a navigation section for now. -Welcome to the Slycot (`slycot`) User's Manual. -This manual contains information on using the `slycot` package, -including documentation for all functions in the package and examples illustrating their use. +:orphan: Installation ============ @@ -48,19 +44,4 @@ Alternatively, to install from source, first `download the source `_ and unpack it. To install in your home directory, use:: - pip install . - -Getting started -=============== - -There are two different ways to use the package. For the default interface -described in :ref:`function-ref`, simply import the slycot package as follows:: - - >>> import slycot - -.. warning:: - In general, the second way is not recommended. - - To access the f2py interface described in :ref:`inner_function-ref`, simply import the slycot package as follows:: - - >>> import slycot._wrapper \ No newline at end of file + pip install . \ No newline at end of file