diff --git a/.gitignore b/.gitignore index 080718f9..bff4fb3a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +doc/_build +doc/generated +doc/source/reference/generated/ .DS_Store* MANIFEST dist/ @@ -12,3 +15,4 @@ build.log *~ setup.cfg _skbuild + diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 00000000..d0c3cbf1 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/doc/make.bat b/doc/make.bat new file mode 100644 index 00000000..747ffb7b --- /dev/null +++ b/doc/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/doc/requirements.txt b/doc/requirements.txt new file mode 100644 index 00000000..2fd39a11 --- /dev/null +++ b/doc/requirements.txt @@ -0,0 +1,13 @@ +sphinx>=7.2.6 +sphinx-copybutton +numpy +scipy +pandas +matplotlib +matplotlib_venn +sphinx_rtd_theme>=2.0.0 +numpydoc +ipykernel +nbsphinx +docutils +#docutils==0.16 # pin until sphinx_rtd_theme is compatible with 0.17 or later diff --git a/doc/source/conf.py b/doc/source/conf.py new file mode 100644 index 00000000..725d2a1b --- /dev/null +++ b/doc/source/conf.py @@ -0,0 +1,50 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- 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')) + +master_doc = "index" +from datetime import date +project = 'Slycot' +copyright = f'{date.today().year}, Slycot Developers' +author = 'Slycot Developers' + +# Version information - read from the source code +import re + +# Get the version number for this commmit (including alpha/beta/rc tags) +release = re.sub('^v', '', os.popen('git describe --tags').read().strip()) + +# The short X.Y.Z version +version = re.sub(r'(\d+\.\d+\.\d+(.post\d+)?)(.*)', r'\1', release) + +print("version %s, release %s" % (version, release)) + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + 'sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.napoleon', + 'sphinx.ext.intersphinx', 'sphinx.ext.imgmath', + 'sphinx.ext.autosummary', 'nbsphinx', 'numpydoc', + 'sphinx.ext.doctest', 'sphinx_copybutton' +] +# scan documents for autosummary directives and generate stub pages for each. +autosummary_generate = True + +templates_path = ['_templates'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = 'sphinx_rtd_theme' +html_static_path = ['_static'] diff --git a/doc/source/contributing/index.rst b/doc/source/contributing/index.rst new file mode 100644 index 00000000..e1ccbbf0 --- /dev/null +++ b/doc/source/contributing/index.rst @@ -0,0 +1,30 @@ +.. 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: + +- `git `_ +- `github `_ +- `Sphinx `_ +- `reStructuredText `_ +- `numpydoc `_ +- `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 `_, which is currently a part of `NumPy `_. \ 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/explanation/inspect_slicot_slycot.ipynb b/doc/source/explanation/inspect_slicot_slycot.ipynb new file mode 100644 index 00000000..2123f1a6 --- /dev/null +++ b/doc/source/explanation/inspect_slicot_slycot.ipynb @@ -0,0 +1,706 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Inspect Slycot vs SLICOT" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook shows how to inspect the slycot module and the slicot libary.\n", + "The result gives us a insight which slicot routines are implemented slycot." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'0.5.5.dev84+g9815526'" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import re\n", + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "from matplotlib_venn import venn2\n", + "\n", + "import slycot\n", + "slycot.__version__" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Helper function" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [], + "source": [ + "def print_list_chunks(routines_list, n=8):\n", + " \"\"\"Print list in chunks of lists.\"\"\"\n", + " start = 0\n", + " end = len(routines_list)\n", + " step = n\n", + " for i in range(start, end, step):\n", + " x = i\n", + " print(routines_list[x:x+step])" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [], + "source": [ + "def get_slycot_routines(sly):\n", + " all_attributes = dir(sly)\n", + " r = re.compile(\"[a-z][a-z][0-9][0-9a-z][a-z][a-z]\")\n", + " matched_attributes = list(filter(r.match, all_attributes)) # Read Note below\n", + " return matched_attributes" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Inspect function" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "There are currently 56 routines that are found in slycot.\n", + "------\n", + "['ab01nd', 'ab04md', 'ab05md', 'ab05nd', 'ab07nd', 'ab08nd', 'ab08nz', 'ab09ad']\n", + "['ab09ax', 'ab09bd', 'ab09md', 'ab09nd', 'ab13bd', 'ab13dd', 'ab13ed', 'ab13fd']\n", + "['ab13md', 'ag08bd', 'mb02ed', 'mb03rd', 'mb03vd', 'mb03vy', 'mb03wd', 'mb05md']\n", + "['mb05nd', 'mc01td', 'sb01bd', 'sb02md', 'sb02mt', 'sb02od', 'sb03md', 'sb03md57']\n", + "['sb03od', 'sb04md', 'sb04qd', 'sb10ad', 'sb10dd', 'sb10fd', 'sb10hd', 'sb10jd']\n", + "['sb10yd', 'sg02ad', 'sg03ad', 'sg03bd', 'tb01id', 'tb01pd', 'tb03ad', 'tb04ad']\n", + "['tb05ad', 'tc01od', 'tc04ad', 'td04ad', 'tf01md', 'tf01rd', 'tg01ad', 'tg01fd']\n", + "None\n", + "\n", + "\n", + "There are currently 607 routines that are found in slicot.\n", + "------\n", + "['mb01wd', 'tg01gd', 'ab13fd', 'sg03ay', 'mb01oe', 'mb02fd', 'tg01oa', 'dg01ny']\n", + "['sg03ax', 'fb01qd', 'ma02az', 'mc01md', 'md03by', 'tf01mx', 'ib01nd', 'mb02rz']\n", + "['mb04bp', 'tb01kd', 'ab09gd', 'ma02jz', 'ud01cd', 'ib01rd', 'nf01bx', 'mb02rd']\n", + "['ma02es', 'mb04iy', 'tg01id', 'mb01rd', 'mc01xd', 'mb04wr', 'sg03bs', 'mb03kc']\n", + "['ma02cd', 'tb04ad', 'md03bx', 'mb03vy', 'ab09cd', 'tf01nd', 'sb09md', 'sb03ot']\n", + "['mb04pu', 'mb04yd', 'mb02pd', 'mb04tu', 'mb02ud', 'ib01cd', 'mb04dp', 'tg01fz']\n", + "['sb04od', 'nf01ad', 'mb03qd', 'ab09bd', 'mb02jd', 'sb02mw', 'ma02ad', 'mb04dl']\n", + "['sb08ed', 'tb01uy', 'md03ba', 'ab05nd', 'mb03pd', 'sb02mx', 'sb04ow', 'ma02mz']\n", + "['mb02cy', 'ag08by', 'mb03bb', 'ab09cx', 'mb01kd', 'sb02sd', 'mb01xd', 'sb01md']\n", + "['mb02ny', 'sb02ox', 'sb10pd', 'ma01cd', 'tg01hd', 'mb02nd', 'sb02cx', 'sb04px']\n", + "['mb03qg', 'tg01hx', 'mb03ag', 'mc01py', 'mb03kb', 'mb04jd', 'tg01bd', 'tb03ay']\n", + "['ab13ed', 'sb03rd', 'ma02id', 'ma02md', 'sb03os', 'mb02cv', 'mb05oy', 'sb06nd']\n", + "['nf01bp', 'sb02od', 'mb03md', 'fb01vd', 'ma02iz', 'tb01ld', 'mb02sd', 'tb01nd']\n", + "['ud01md', 'mb02xd', 'mb02md', 'sg03br', 'mb04az', 'sb02ru', 'sb10qd', 'sg03bu']\n", + "['sb04qr', 'mb03lf', 'ma01ad', 'sb04rd', 'ma02gd', 'sb04ry', 'ab13ad', 'ab13md']\n", + "['nf01by', 'mb04nd', 'mb03yt', 'sg02cx', 'tg01hu', 'ab09kx', 'mb04hd', 'mb03gd']\n", + "['sb08cd', 'mb03od', 'sb04mr', 'mb02kd', 'ab09jx', 'ud01bd', 'fb01sd', 'mb03rd']\n", + "['ab07nd', 'mb03fd', 'sb03ou', 'mb03ya', 'mb01rh', 'sb08hd', 'ab08nw', 'ab07md']\n", + "['ab05qd', 'mb02qy', 'mb03id', 'ma02bd', 'ma02dd', 'mb04ed', 'sb03td', 'mb04tv']\n", + "['td04ad', 'tb01ud', 'tc01od', 'nf01bs', 'ma02oz', 'sg02nd', 'mb04ru', 'mc01rd']\n", + "['mb03bd', 'mb04tt', 'sb08ny', 'tg01ad', 'sb04qu', 'nf01bf', 'tg01qd', 'mc01td']\n", + "['mb04fp', 'mb03ud', 'mb3lzp', 'sb04nv', 'mb04qb', 'mb04wp', 'mc01sy', 'sb10dd']\n", + "['mb02sz', 'mb04kd', 'tb04bw', 'mb01ry', 'sb03mv', 'tb03ad', 'mb03gz', 'mb01ot']\n", + "['mb03be', 'tb01zd', 'ab04md', 'mb01os', 'sb03qx', 'mb04pb', 'nf01bu', 'mb04su']\n", + "['mc01od', 'sb16bd', 'mb02td', 'sg03ad', 'sb03qy', 'mb03xs', 'md03bb', 'mb04qc']\n", + "['mb03jd', 'sb01by', 'ab09nd', 'sb03md', 'mb04oy', 'mb05nd', 'ab08nx', 'mb01rb']\n", + "['dg01md', 'mb02wd', 'sb03ud', 'mb03py', 'mc01pd', 'ma02pz', 'ab09iy', 'ma02od']\n", + "['sb10td', 'tf01my', 'sb16cy', 'tg01oz', 'ab05pd', 'mb04cd', 'sb16ay', 'sb10hd']\n", + "['mb02gd', 'mc03md', 'mb03bc', 'sb04nx', 'mc01qd', 'ab01od', 'ab09jd', 'sb16ad']\n", + "['sg03bv', 'nf01bb', 'ab09dd', 'mb03lp', 'md03bf', 'mb03ah', 'mb3jzp', 'sb04mu']\n", + "['ab09kd', 'sb03ov', 'sb03pd', 'fd01ad', 'sb03sd', 'td05ad', 'mb02hd', 'mb02cd']\n", + "['mb03qx', 'sb04nd', 'mb04tb', 'sb04pd', 'tg01jy', 'tb04cd', 'tg01dd', 'ab09ed']\n", + "['mb03wx', 'tg01pd', 'tf01pd', 'sb08fd', 'ab13ax', 'nf01ba', 'sb08md', 'mb04dy']\n", + "['sb04my', 'ab09fd', 'mb04vd', 'mb01md', 'ib01oy', 'mb04ld', 'sb01bd', 'sb02mu']\n", + "['sg03bx', 'tg01ed', 'mb02qd', 'mb01ss', 'mb01rw', 'sb10ud', 'mb03cz', 'ag8byz']\n", + "['sb02ow', 'mb02dd', 'sb08nd', 'mb03my', 'mb03yd', 'tg01od', 'mc01sw', 'ma02bz']\n", + "['ib01ad', 'ab09hd', 'ud01mz', 'td03ad', 'sb03my', 'ib03bd', 'mb04dd', 'mb04xd']\n", + "['ma02hd', 'ab09ax', 'tg01hy', 'mc01sx', 'tb01ux', 'df01md', 'mb04vx', 'mb04wd']\n", + "['ab08md', 'tb01vd', 'nf01ay', 'md03bd', 'mb03rz', 'ab09ix', 'ab13dd', 'tb01iz']\n", + "['nf01bw', 'mb04qf', 'ab05sd', 'mb04db', 'mb03ai', 'sb08gd', 'mb02od', 'mb04ty']\n", + "['mb02uv', 'ib01px', 'tb01ty', 'sb03oy', 'sb03mu', 'tg01nd', 'ab09hx', 'ab09id']\n", + "['mb04id', 'mb03ed', 'mb04di', 'mb04tx', 'sb03od', 'mb04xy', 'mb03hz', 'tc04ad']\n", + "['mb01rx', 'sb02ov', 'mb03zd', 'mb03jp', 'mb02yd', 'mb04ox', 'bd01ad', 'mb04fd']\n", + "['ab05md', 'tb04bx', 'dg01od', 'sb10zd', 'mb01rt', 'sb02mr', 'ab01nd', 'mb04bz']\n", + "['ma01bz', 'ma02ed', 'mb03ld', 'tb01md', 'tb01xz', 'mb04qs', 'ab09md', 'sb10id']\n", + "['sb03sx', 'mb02cu', 'ab13bd', 'mb3oyz', 'mb02tz', 'tb01px', 'mb03iz', 'sg03bw']\n", + "['mb04dz', 'nf01bv', 'bd02ad', 'tf01md', 'mb03wd', 'mb4dbz', 'mb04tw', 'mb03vd']\n", + "['mb01oo', 'fb01rd', 'mb04rb', 'mb03ry', 'mb01xy', 'tb05ad', 'ib03ad', 'mb03xz']\n", + "['mb05md', 'mb02ed', 'sb03mw', 'sg03bd', 'mb01ru', 'mb01oc', 'bb02ad', 'ab09jw']\n", + "['mb03cd', 'mb04pa', 'sb10yd', 'mb02jx', 'tg01az', 'sg02ad', 'ma02hz', 'mb03dz']\n", + "['tg01md', 'sb08my', 'tb04ay', 'sb02nd', 'sb02mt', 'sb04rw', 'mb04wu', 'nf01be']\n", + "['de01pd', 'sb02mv', 'sb10ed', 'sb10zp', 'mb03lz', 'sb02oy', 'sb04md', 'mb03bg']\n", + "['mb03ad', 'mb01uw', 'sb10kd', 'ma02jd', 'ma02gz', 'tf01qd', 'mb03td', 'mb04gd']\n", + "['tb04bv', 'tg01ld', 'mb03ba', 'ue01md', 'mb3pyz', 'mb03xp', 'sb02ou', 'mb01nd']\n", + "['sg02cw', 'mb04yw', 'sb04mw', 'mb01uy', 'sg03by', 'ib01py', 'mb02uw', 'tg01ob']\n", + "['mb03jz', 'mb04ad', 'tg01fd', 'mb03sd', 'ab13id', 'ab08ny', 'mb03za', 'mb02uu']\n", + "['ab08nd', 'mc01wd', 'tg01ly', 'mb01uz', 'mb03xu', 'mb03nd', 'ag07bd', 'sg03bt']\n", + "['mb03xd', 'ma02nz', 'ab13dx', 'ab08nz', 'sb04ny', 'mb03ts', 'sb04qy', 'mb03rx']\n", + "['mb03af', 'ib01md', 'mb03ke', 'sb02pd', 'sb16cd', 'ab8nxz', 'mb04bd', 'tf01rd']\n", + "['mb01ux', 'mb03bz', 'sb03sy', 'mc03ny', 'sb10ld', 'ma02fd', 'td03ay', 'bb04ad']\n", + "['mb03ab', 'dk01md', 'ab05od', 'mc03nx', 'mb01td', 'tb01id', 'tg01cd', 'mb04ow']\n", + "['sb04nw', 'mb03ae', 'mb03rw', 'mb03qy', 'sb04py', 'nf01bq', 'mb03dd', 'tb01kx']\n", + "['mb01ud', 'ma01bd', 'mb03ny', 'ab08mz', 'sb02rd', 'sb04qd', 'tb01wx', 'ag08bz']\n", + "['tg01wd', 'tb04bd', 'sb02md', 'bb01ad', 'mc01sd', 'mc01vd', 'sb10ad', 'mb01vd']\n", + "['de01od', 'ib01pd', 'mb03bf', 'sb02ms', 'mb04py', 'mc03nd', 'tb01wd', 'mc01nd']\n", + "['dg01nd', 'ab09ad', 'mb02id', 'tb01yd', 'sb03mx', 'mb03vw', 'sg02cv', 'ab05rd']\n", + "['mb04ds', 'mb01od', 'mb4dpz', 'mb03oy', 'sb03qd', 'sb01bx', 'sb08dd', 'ib01od']\n", + "['sb10md', 'mb01ld', 'mb04iz', 'mb05od', 'tb01td', 'mb02vd', 'mb03fz', 'mb05my']\n", + "['mb01oh', 'mb04zd', 'sb03oz', 'tg01kz', 'mb02cx', 'tg01jd', 'mb01zd', 'mb01pd']\n", + "['sb01dd', 'mb03hd', 'sb02qd', 'mb03qw', 'tb01xd', 'ud01nd', 'sb10rd', 'ib01my']\n", + "['tf01od', 'ud01dd', 'tb01vy', 'ab09hy', 'sb04rx', 'ib01qd', 'mb04od', 'mb03qv']\n", + "['sg03bz', 'sb03or', 'mb03kd', 'ab13cd', 'tg01kd', 'mb03wa', 'mb04ts', 'mb03ka']\n", + "['mb4dlz', 'mb04qu', 'sb10fd', 'ma02pd', 'sb10jd', 'mb01qd', 'ab09jv', 'sb10vd']\n", + "['fb01td', 'ma02ez', 'tc05ad', 'sb10wd', 'md03ad', 'nf01bd', 'ma02cz', 'mb04ny']\n", + "['sb04rv', 'nf01br', 'tb01pd', 'ab01md', 'ib01bd', 'mb01yd', 'tg01nx', 'sb01fy']\n", + "['mb04md', 'sb10sd', 'mb04ud', 'mb01sd', 'ag08bd', 'ab09bx', 'bb03ad']\n", + "None\n" + ] + } + ], + "source": [ + "slycot_routines = get_slycot_routines(slycot)\n", + "\n", + "print(f\"There are currently {len(slycot_routines)} routines that are found in slycot.\")\n", + "print(\"------\")\n", + "print(print_list_chunks(slycot_routines))\n", + "print(\"\\n\")\n", + "\n", + "with open('slicot_routines.txt') as f:\n", + " lines = f.readlines()\n", + "\n", + "slicot_routines = [x.split(\"\\n\")[0] for x in lines]\n", + "\n", + "print(f\"There are currently {len(slicot_routines)} routines that are found in slicot.\")\n", + "print(\"------\")\n", + "print(print_list_chunks(slicot_routines))" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Generate Sets for the Venn-Diagramm" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "There are currently 1 routines that are found in slycot and not in slicot.\n", + "------\n", + "['sb03md57']\n", + "None\n", + "\n", + "\n", + "There are currently 552 routines that are found in slicot and not in slycot.\n", + "------\n", + "['mb04cd', 'mb3pyz', 'ma02fd', 'ib03bd', 'mb03qx', 'mb02ud', 'mb03bz', 'ma02es']\n", + "['ma02az', 'mb02od', 'mb03iz', 'sb10vd', 'ab09ed', 'mb03oy', 'sb10zd', 'tb01uy']\n", + "['mb04iy', 'tb01wx', 'ud01nd', 'ma02gd', 'mb04ty', 'ma02bz', 'mb03jd', 'mc01vd']\n", + "['mb01ld', 'mb04ny', 'ud01cd', 'mb03hz', 'ma02hz', 'mb03td', 'ab13cd', 'mb04fp']\n", + "['mb02jd', 'ab13ad', 'fb01td', 'mb03dz', 'mb03kb', 'nf01be', 'mb3jzp', 'tb01xz']\n", + "['mb03kd', 'sb03oy', 'md03bb', 'mb04ld', 'mb03ag', 'fd01ad', 'sb02ox', 'mb03jz']\n", + "['tf01qd', 'mb01oo', 'nf01bw', 'mb03xz', 'ab09ix', 'mb04ed', 'tg01az', 'tg01qd']\n", + "['ma02nz', 'nf01bp', 'tb04bd', 'ma02iz', 'mb04nd', 'mb01ud', 'mb03af', 'mb3lzp']\n", + "['mb03yt', 'mb04qc', 'sg03by', 'sb04pd', 'mb04wu', 'mb04pb', 'nf01bs', 'ma02ez']\n", + "['sb04qy', 'mb03qy', 'sb04mu', 'mb03ya', 'sb04ry', 'bb01ad', 'sb10rd', 'mb03ts']\n", + "['mb01xd', 'mb04qu', 'mb03fd', 'sb10md', 'sb10ud', 'mb04dp', 'ab08md', 'nf01ay']\n", + "['mb02vd', 'mb01kd', 'tb01zd', 'mb02pd', 'mb03ny', 'ud01bd', 'tg01gd', 'ma02ed']\n", + "['mb03bd', 'ab09jx', 'mb02id', 'mb03wx', 'tb01kd', 'mb01oh', 'mb04tb', 'tb01kx']\n", + "['mb01vd', 'sb03mu', 'mb02jx', 'mb04yw', 'md03bd', 'mb02uv', 'nf01ad', 'tg01oz']\n", + "['sg02cv', 'mb03wa', 'sb02ms', 'tb01px', 'ab09bx', 'ab09kd', 'ab09cx', 'mb01yd']\n", + "['ib01bd', 'ab05pd', 'mb03ba', 'tg01hx', 'mb03rz', 'mb03bf', 'sb10sd', 'sb08fd']\n", + "['sb16bd', 'sb02mr', 'tg01wd', 'mb04tt', 'nf01bq', 'sb10qd', 'sb16ay', 'dk01md']\n", + "['sb04rw', 'td05ad', 'mb01od', 'tg01dd', 'md03bf', 'mb04gd', 'mb04bd', 'mb04hd']\n", + "['sb04mw', 'mb01rt', 'mb03bb', 'mb03dd', 'dg01ny', 'mb01uy', 'mb01uw', 'mb4dpz']\n", + "['mb03bc', 'sb03pd', 'nf01bd', 'sb03oz', 'tg01fz', 'ab09kx', 'sb03td', 'ag08bz']\n", + "['sb06nd', 'ib01rd', 'de01pd', 'tc05ad', 'mb04ru', 'sb04mr', 'ab08nx', 'dg01nd']\n", + "['mc03ny', 'ma02md', 'sb02ov', 'ab09jd', 'tg01cd', 'mb01zd', 'sb04nd', 'mb01xy']\n", + "['sb08nd', 'ab09iy', 'tg01nd', 'mb03zd', 'sb10id', 'td03ay', 'tb01vd', 'mb03lp']\n", + "['sb16ad', 'tf01pd', 'mb03cz', 'ma02id', 'mb02qy', 'ab01od', 'mb03hd', 'sb02sd']\n", + "['tf01my', 'sb03ou', 'tb01ux', 'mb04xy', 'mb02dd', 'mb04wr', 'ib01ad', 'nf01bu']\n", + "['nf01bf', 'tg01md', 'mb02cx', 'mb03xp', 'tb01nd', 'tg01ob', 'mb03xu', 'nf01bb']\n", + "['sb01fy', 'mb03qd', 'ab05sd', 'mb02sz', 'ma02hd', 'mb02td', 'mc01sy', 'mb03ad']\n", + "['sb04px', 'mb01rx', 'mb01os', 'tf01od', 'mb04dd', 'tg01jd', 'mb04tv', 'sb10kd']\n", + "['sb01bx', 'sb04nx', 'mb01nd', 'tb01ty', 'ma01bz', 'mb04ds', 'mc01qd', 'de01od']\n", + "['mb04oy', 'ma02jd', 'mb03ae', 'mb01sd', 'mb02qd', 'sb01dd', 'ab13ax', 'ud01mz']\n", + "['mc01sd', 'sb03or', 'mb04md', 'sb04od', 'sb03rd', 'md03ad', 'ab09fd', 'tg01id']\n", + "['sb08cd', 'sb03sd', 'mb02yd', 'ab8nxz', 'mb01rd', 'ma02bd', 'ib01my', 'sb02nd']\n", + "['ib01pd', 'sb08gd', 'mb04pu', 'mb02cy', 'mc01sx', 'ib01py', 'mb03rx', 'mb02cd']\n", + "['ab09hx', 'mb02cv', 'dg01od', 'ma02cz', 'tf01mx', 'tb01ld', 'tg01hy', 'mb03xd']\n", + "['mc01py', 'ab13id', 'mb04zd', 'mb04py', 'mb01md', 'tb01md', 'sb10ld', 'mb02sd']\n", + "['mb02rz', 'ab07md', 'mb02xd', 'ag8byz', 'sg03bu', 'mb02uu', 'mb02uw', 'ab09gd']\n", + "['mb03qw', 'sb04qr', 'sb03mw', 'sb16cd', 'sb04rd', 'sg03bv', 'ag07bd', 'mc01sw']\n", + "['sb08md', 'mb01ru', 'sb04ow', 'tg01kz', 'mb03ud', 'fb01vd', 'mb01rh', 'td03ad']\n", + "['md03bx', 'mb02fd', 'tg01bd', 'sb02ow', 'mb01uz', 'ab08mz', 'mb01pd', 'mb01qd']\n", + "['ma02mz', 'mb01ry', 'sb03sy', 'sb02mu', 'mb03ka', 'mb04ts', 'sb02rd', 'mb01rw']\n", + "['sb03mv', 'nf01by', 'sb10ed', 'ab08ny', 'ib03ad', 'sb02mx', 'dg01md', 'mb03yd']\n", + "['sb10td', 'sb02cx', 'ib01od', 'mb04fd', 'sg03bw', 'sb08ed', 'ab09dd', 'tb01yd']\n", + "['tb01xd', 'bd01ad', 'sb02oy', 'mb03bg', 'mb03nd', 'mb04qs', 'ma02pd', 'md03ba']\n", + "['tg01ld', 'mb03ed', 'mb03ld', 'ib01nd', 'mb02md', 'tb04bw', 'mb01td', 'mb02kd']\n", + "['tg01oa', 'mb04bz', 'mb03my', 'mb04dy', 'fb01sd', 'sb10pd', 'mb04xd', 'fb01qd']\n", + "['sb03ov', 'mc01wd', 'mb4dbz', 'tg01jy', 'ib01oy', 'sg03ay', 'ab09hy', 'sb02ru']\n", + "['sb10zp', 'mb04iz', 'mb05oy', 'sb04rv', 'tg01ed', 'tg01od', 'tg01pd', 'mb04vx']\n", + "['mb03pd', 'mb04di', 'ib01px', 'ib01md', 'ag08by', 'ab09id', 'tb01iz', 'ab09jv']\n", + "['ud01dd', 'mb03lz', 'mb03rw', 'sb04rx', 'mb03lf', 'sb10wd', 'mb04dl', 'mb01ux']\n", + "['mb03ry', 'mb03xs', 'mb03qv', 'sb02ou', 'ma02gz', 'ma02cd', 'sb04qu', 'tg01ly']\n", + "['ue01md', 'sb03mx', 'nf01br', 'sg03ax', 'mc01nd', 'mb03ai', 'nf01bv', 'mc01xd']\n", + "['tb04bv', 'sg02cx', 'bd02ad', 'sb03qx', 'sg03bt', 'sb01by', 'mb05my', 'ib01cd']\n", + "['mb02ny', 'mb02nd', 'mb02hd', 'ma01bd', 'sb02mw', 'sb16cy', 'ab09hd', 'mb03ah']\n", + "['tb01vy', 'sb08dd', 'ma01cd', 'mb04yd', 'tg01kd', 'mb03za', 'mb01oe', 'ab13dx']\n", + "['ma02od', 'sb02pd', 'sb03os', 'mc01od', 'mb04wd', 'mb03vw', 'tb01wd', 'mb03gd']\n", + "['mb04od', 'sb02qd', 'sb09md', 'ab09jw', 'mc01md', 'ma02ad', 'df01md', 'mb04db']\n", + "['mc03nd', 'tf01nd', 'ma02dd', 'mb04su', 'sb08my', 'mb04tu', 'mb04vd', 'sg02nd']\n", + "['mb02cu', 'sg02cw', 'sb04nv', 'mb03fz', 'mb3oyz', 'mb03md', 'mb01rb', 'mb02rd']\n", + "['sb03qd', 'sb03ot', 'mb02gd', 'ab05qd', 'mb03be', 'mb03cd', 'ud01md', 'mb04ud']\n", + "['mb03ke', 'mc03md', 'ab01md', 'sg03br', 'sb02mv', 'nf01ba', 'mb01oc', 'bb03ad']\n", + "['tb03ay', 'ma02oz', 'tb04cd', 'mb03sd', 'sb04my', 'sb03qy', 'mb04ox', 'tb01td']\n", + "['mb04dz', 'mb04kd', 'mb04qb', 'mb04tw', 'mb04pa', 'mb03id', 'bb04ad', 'ma01ad']\n", + "['ab08nw', 'mb03ab', 'ib01qd', 'sg03bz', 'mb04wp', 'mb02wd', 'mb03qg', 'mb04qf']\n", + "['sg03bx', 'mb04id', 'tb01ud', 'mb04tx', 'ab05rd', 'ma02jz', 'mb02tz', 'sb03ud']\n", + "['mb01wd', 'mc01rd', 'mb04bp', 'sb01md', 'tg01hd', 'tg01nx', 'md03by', 'sb03sx']\n", + "['mb04az', 'mb4dlz', 'mb01ot', 'sb08hd', 'tb04bx', 'tg01hu', 'mb03jp', 'ab05od']\n", + "['mc03nx', 'mb04rb', 'mc01pd', 'mb01ss', 'fb01rd', 'sb03my', 'tb04ay', 'bb02ad']\n", + "['mb03kc', 'sb04nw', 'mb04jd', 'sb04ny', 'mb04ow', 'sb08ny', 'mb03od', 'mb05od']\n", + "['ab09cd', 'nf01bx', 'sg03bs', 'mb03py', 'ma02pz', 'mb03gz', 'mb04ad', 'sb04py']\n", + "None\n", + "\n", + "\n" + ] + } + ], + "source": [ + "not_in_slicot = list(set(slycot_routines)- set(slicot_routines))\n", + "not_in_slicot\n", + "\n", + "print(f\"There are currently {len(not_in_slicot)} routines that are found in slycot and not in slicot.\")\n", + "print(\"------\")\n", + "print(print_list_chunks(not_in_slicot))\n", + "print(\"\\n\")\n", + "\n", + "not_in_slycot = list(set(slicot_routines) - set(slycot_routines))\n", + "not_in_slycot\n", + "\n", + "print(f\"There are currently {len(not_in_slycot)} routines that are found in slicot and not in slycot.\")\n", + "print(\"------\")\n", + "print(print_list_chunks(not_in_slycot))\n", + "print(\"\\n\")" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "There are currently 608 routines that are found in slicot or in slycot. (union)\n", + "------\n", + "['mb04cd', 'mb3pyz', 'ab08nz', 'ma02fd', 'ib03bd', 'mb03qx', 'mb02ud', 'mb03bz']\n", + "['ma02es', 'ma02az', 'mb02od', 'mb03iz', 'sb10vd', 'ab09ed', 'mb03oy', 'sb10zd']\n", + "['tb01uy', 'ab04md', 'mb04iy', 'tb01wx', 'ud01nd', 'ma02gd', 'mb04ty', 'ma02bz']\n", + "['mb03jd', 'mc01vd', 'mb01ld', 'mb04ny', 'ud01cd', 'ab13md', 'mb03hz', 'ma02hz']\n", + "['mb03td', 'ab13cd', 'mb04fp', 'mb02jd', 'ab13ad', 'fb01td', 'mb03dz', 'mb03kb']\n", + "['nf01be', 'mb3jzp', 'tb01xz', 'sg03ad', 'mb03kd', 'sb03oy', 'md03bb', 'mb04ld']\n", + "['mb03ag', 'fd01ad', 'sb02ox', 'mb03jz', 'tf01qd', 'mb01oo', 'nf01bw', 'mb03xz']\n", + "['ab09ix', 'mb04ed', 'tg01az', 'tg01qd', 'ma02nz', 'nf01bp', 'tb04bd', 'ma02iz']\n", + "['mb04nd', 'mb01ud', 'mb03af', 'mb3lzp', 'mb03yt', 'mb04qc', 'ab01nd', 'sg03by']\n", + "['sb04pd', 'sb03md', 'mb04wu', 'mb04pb', 'nf01bs', 'ma02ez', 'sb04qy', 'mb03qy']\n", + "['sb04mu', 'mb03ya', 'ab09md', 'sb04ry', 'bb01ad', 'sb10rd', 'mb03ts', 'mb01xd']\n", + "['mb04qu', 'mb03fd', 'sb10md', 'sb10ud', 'tb04ad', 'mb04dp', 'ab08md', 'nf01ay']\n", + "['mb02vd', 'mb01kd', 'tb01zd', 'mb02pd', 'tb05ad', 'mb03ny', 'ud01bd', 'tg01gd']\n", + "['ma02ed', 'mb03bd', 'ab09jx', 'mb02id', 'ab09nd', 'mb03wx', 'tb01kd', 'mb01oh']\n", + "['mb04tb', 'tb01kx', 'mb01vd', 'sb03mu', 'mb02jx', 'mb04yw', 'md03bd', 'mb02uv']\n", + "['nf01ad', 'tg01oz', 'sg02cv', 'mb03wa', 'sb02ms', 'tb01px', 'ab09bx', 'ab09kd']\n", + "['ab09cx', 'mb01yd', 'ib01bd', 'ab05pd', 'mb03ba', 'tg01hx', 'mb03rz', 'mb03bf']\n", + "['sb10sd', 'mb03wd', 'sb08fd', 'sb16bd', 'sb02mr', 'tg01wd', 'mb04tt', 'nf01bq']\n", + "['sb10qd', 'mb02ed', 'sb16ay', 'sg03bd', 'dk01md', 'sb04rw', 'td05ad', 'mb01od']\n", + "['tg01dd', 'mb05nd', 'md03bf', 'mb04gd', 'sg02ad', 'mb04bd', 'mb04hd', 'sb04mw']\n", + "['ab13ed', 'mb01rt', 'mb03bb', 'mb03dd', 'dg01ny', 'mb01uy', 'mb01uw', 'mb4dpz']\n", + "['mb03bc', 'sb03pd', 'nf01bd', 'sb03oz', 'tg01fz', 'ab09kx', 'sb03td', 'ag08bz']\n", + "['sb06nd', 'ib01rd', 'de01pd', 'tc05ad', 'mb04ru', 'sb04mr', 'ab08nx', 'dg01nd']\n", + "['mc03ny', 'ma02md', 'sb02ov', 'ab09jd', 'tg01cd', 'mb01zd', 'sb04nd', 'mb01xy']\n", + "['sb08nd', 'ab09iy', 'tg01nd', 'mb03zd', 'sb10id', 'td03ay', 'tb01vd', 'mb03lp']\n", + "['sb16ad', 'mb03rd', 'tf01pd', 'mb03cz', 'ma02id', 'mb02qy', 'ab01od', 'mb03hd']\n", + "['sb02sd', 'tf01my', 'sb03ou', 'tb01ux', 'mb04xy', 'mb02dd', 'mb04wr', 'ib01ad']\n", + "['nf01bu', 'nf01bf', 'tg01md', 'mb02cx', 'mb03xp', 'tb01nd', 'tg01ob', 'mb03xu']\n", + "['nf01bb', 'sb01fy', 'mb03qd', 'ab05sd', 'mb02sz', 'ma02hd', 'mb02td', 'mc01sy']\n", + "['mb03ad', 'sb04px', 'mb01rx', 'mb01os', 'tf01od', 'mb04dd', 'tg01jd', 'mb04tv']\n", + "['sb10kd', 'sb01bx', 'sb04nx', 'mb01nd', 'tb01ty', 'ma01bz', 'mb04ds', 'mc01qd']\n", + "['de01od', 'mb04oy', 'ma02jd', 'mb03ae', 'mb01sd', 'mb02qd', 'sb01dd', 'sb02mt']\n", + "['ab13ax', 'ud01mz', 'mc01sd', 'sb03or', 'ab13bd', 'mb04md', 'sb04od', 'sb03rd']\n", + "['md03ad', 'ab09fd', 'tg01id', 'sb08cd', 'sb03sd', 'mb02yd', 'ab8nxz', 'mb01rd']\n", + "['ma02bd', 'ib01my', 'sb02nd', 'ib01pd', 'sb08gd', 'mb04pu', 'mb02cy', 'mc01sx']\n", + "['ib01py', 'mb03rx', 'mb02cd', 'ab09hx', 'mb02cv', 'dg01od', 'ma02cz', 'tf01mx']\n", + "['tb01ld', 'tg01hy', 'mb03xd', 'tb01id', 'ab05nd', 'mc01py', 'ab13id', 'mb04zd']\n", + "['mb04py', 'mb01md', 'tb01md', 'sb10ld', 'mb02sd', 'mb02rz', 'ab07md', 'mb02xd']\n", + "['ag8byz', 'sg03bu', 'mb02uu', 'mb02uw', 'ab09gd', 'mb03qw', 'sb04qr', 'sb03mw']\n", + "['sb16cd', 'sb04rd', 'sg03bv', 'ag07bd', 'mc01sw', 'sb08md', 'mb01ru', 'sb04ow']\n", + "['tg01kz', 'mb03ud', 'fb01vd', 'mb01rh', 'td03ad', 'md03bx', 'mb02fd', 'tg01bd']\n", + "['sb02ow', 'mb01uz', 'tc04ad', 'ab08mz', 'mb01pd', 'mb01qd', 'ma02mz', 'mb01ry']\n", + "['sb03sy', 'sb02mu', 'mb03ka', 'mb04ts', 'sb02rd', 'mb01rw', 'sb03mv', 'nf01by']\n", + "['sb10ed', 'sb02od', 'ab08ny', 'sb04qd', 'ib03ad', 'sb02mx', 'tc01od', 'dg01md']\n", + "['mb03yd', 'sb10td', 'sb02cx', 'ib01od', 'mb04fd', 'sg03bw', 'sb08ed', 'sb03md57']\n", + "['ab09dd', 'tb01yd', 'tb01xd', 'bd01ad', 'sb02oy', 'mb03bg', 'mb03nd', 'mb04qs']\n", + "['ma02pd', 'md03ba', 'tb01pd', 'tg01ld', 'mb03ed', 'mb03ld', 'ib01nd', 'mb02md']\n", + "['tb04bw', 'mb01td', 'mb02kd', 'tg01oa', 'mb04bz', 'mb03my', 'mb04dy', 'fb01sd']\n", + "['sb10pd', 'mb04xd', 'fb01qd', 'sb03ov', 'mc01wd', 'mb4dbz', 'tg01jy', 'ib01oy']\n", + "['sg03ay', 'ab09hy', 'sb02ru', 'sb10zp', 'mb04iz', 'mb05oy', 'sb04rv', 'ab09ad']\n", + "['tg01ed', 'tg01od', 'tg01pd', 'mb04vx', 'mb03pd', 'mb04di', 'ib01px', 'ib01md']\n", + "['ag08by', 'ab09id', 'tb01iz', 'ab13fd', 'ab09jv', 'ud01dd', 'sb10jd', 'mb03lz']\n", + "['mb03rw', 'sb04rx', 'mb03lf', 'sb10wd', 'mb04dl', 'mb03vd', 'mb01ux', 'mb03ry']\n", + "['mb03xs', 'mb03qv', 'sb02ou', 'ma02gz', 'ma02cd', 'sb04qu', 'tg01ly', 'ab05md']\n", + "['ue01md', 'sb03mx', 'sb10ad', 'nf01br', 'sg03ax', 'tb03ad', 'mc01nd', 'td04ad']\n", + "['mb03ai', 'nf01bv', 'mc01xd', 'tb04bv', 'sg02cx', 'bd02ad', 'sb03qx', 'sg03bt']\n", + "['sb01by', 'mb05my', 'ib01cd', 'mb02ny', 'mb02nd', 'sb10hd', 'mb02hd', 'ma01bd']\n", + "['sb02mw', 'sb16cy', 'ab09hd', 'mb03ah', 'tb01vy', 'sb08dd', 'ma01cd', 'mb04yd']\n", + "['tg01kd', 'mb03za', 'mb01oe', 'ab13dx', 'ma02od', 'sb02pd', 'sb03os', 'mc01od']\n", + "['mb04wd', 'mb03vw', 'tb01wd', 'mb03gd', 'mb04od', 'sb02qd', 'sb09md', 'ab09jw']\n", + "['mc01md', 'ma02ad', 'df01md', 'mb04db', 'mc03nd', 'tf01nd', 'ma02dd', 'mb04su']\n", + "['sb08my', 'sb01bd', 'mb04tu', 'mb04vd', 'sg02nd', 'mb02cu', 'sg02cw', 'mb05md']\n", + "['sb04nv', 'mb03fz', 'sb10fd', 'mb3oyz', 'mb03md', 'mb01rb', 'mb02rd', 'sb03qd']\n", + "['sb03ot', 'mb02gd', 'ab05qd', 'mc01td', 'mb03be', 'mb03cd', 'ud01md', 'mb04ud']\n", + "['mb03ke', 'mc03md', 'ab01md', 'sg03br', 'sb02mv', 'nf01ba', 'mb01oc', 'bb03ad']\n", + "['tb03ay', 'ma02oz', 'tb04cd', 'ab13dd', 'mb03sd', 'sb04my', 'sb03qy', 'mb04ox']\n", + "['tb01td', 'mb04dz', 'mb04kd', 'mb04qb', 'mb04tw', 'mb04pa', 'ag08bd', 'mb03id']\n", + "['bb04ad', 'ma01ad', 'ab08nw', 'mb03ab', 'ib01qd', 'sg03bz', 'mb04wp', 'mb03vy']\n", + "['mb02wd', 'mb03qg', 'mb04qf', 'sg03bx', 'mb04id', 'tg01fd', 'ab09bd', 'tb01ud']\n", + "['mb04tx', 'sb04md', 'ab05rd', 'ma02jz', 'ab08nd', 'tf01rd', 'mb02tz', 'sb03ud']\n", + "['mb01wd', 'mc01rd', 'mb04bp', 'sb01md', 'tg01hd', 'tg01nx', 'md03by', 'sb03sx']\n", + "['mb04az', 'mb4dlz', 'mb01ot', 'sb08hd', 'tb04bx', 'tf01md', 'tg01hu', 'mb03jp']\n", + "['sb10yd', 'ab05od', 'mc03nx', 'mb04rb', 'mc01pd', 'mb01ss', 'fb01rd', 'sb03my']\n", + "['ab07nd', 'tb04ay', 'ab09ax', 'bb02ad', 'mb03kc', 'sb04nw', 'mb04jd', 'sb04ny']\n", + "['mb04ow', 'sb02md', 'sb08ny', 'mb03od', 'mb05od', 'sb03od', 'ab09cd', 'nf01bx']\n", + "['sg03bs', 'sb10dd', 'mb03py', 'tg01ad', 'ma02pz', 'mb03gz', 'mb04ad', 'sb04py']\n", + "None\n", + "\n", + "\n", + "There are currently 55 routines that are found in slicot and slycot. (intersection)\n", + "------\n", + "['ab08nz', 'ab13bd', 'tf01md', 'sb10yd', 'sb10jd', 'ag08bd', 'sb03md', 'mb05nd']\n", + "['mb05md', 'ab07nd', 'sg03ad', 'sb10fd', 'sg02ad', 'mb03vd', 'ab09ax', 'sb04qd']\n", + "['mb03vy', 'sb02od', 'sb10hd', 'ab13ed', 'tc01od', 'mb03rd', 'sb02md', 'tg01fd']\n", + "['ab09bd', 'ab09md', 'sb04md', 'mc01td', 'ab04md', 'ab08nd', 'tf01rd', 'tb04ad']\n", + "['tb01id', 'ab05nd', 'ab09ad', 'ab05md', 'sb03od', 'sb10ad', 'mb02ed', 'tb03ad']\n", + "['ab13md', 'mb03wd', 'tb05ad', 'tc04ad', 'sb10dd', 'td04ad', 'tb01pd', 'tg01ad']\n", + "['ab13dd', 'ab09nd', 'sg03bd', 'ab13fd', 'sb02mt', 'sb01bd', 'ab01nd']\n", + "None\n" + ] + } + ], + "source": [ + "union = list(set(slicot_routines) | set(slycot_routines))\n", + "\n", + "print(f\"There are currently {len(union)} routines that are found in slicot or in slycot. (union)\")\n", + "print(\"------\")\n", + "print(print_list_chunks(union))\n", + "print(\"\\n\")\n", + "\n", + "intersection = list(set(slicot_routines) & set(slycot_routines))\n", + "intersection\n", + "\n", + "print(f\"There are currently {len(intersection)} routines that are found in slicot and slycot. (intersection)\")\n", + "print(\"------\")\n", + "print(print_list_chunks(intersection))" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
chapter nameslycot routinesslicot routines
aAnalysis Routines1860
bBenchmark06
cAdaptive Control00
dData Analysis08
fFiltering06
iIdentification015
mMathematical routines8281
nNonlinear Systems016
sSynthesis Routines18131
tTransformation Routines1277
uUtility Routines07
total-56607
\n", + "
" + ], + "text/plain": [ + " chapter name slycot routines slicot routines\n", + "a Analysis Routines 18 60\n", + "b Benchmark 0 6\n", + "c Adaptive Control 0 0\n", + "d Data Analysis 0 8\n", + "f Filtering 0 6\n", + "i Identification 0 15\n", + "m Mathematical routines 8 281\n", + "n Nonlinear Systems 0 16\n", + "s Synthesis Routines 18 131\n", + "t Transformation Routines 12 77\n", + "u Utility Routines 0 7\n", + "total - 56 607" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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ofT29s72WKuFCxdSvHhxGjduDMBvv/1GSkrKLZc5nDp1inLlymU7fv1u/FOnTt3JpREeHo6XlxdLliwxjy1ZsoRq1apRtmxZAJydnXnzzTdZv349RYsW5YknnmDq1KmcPn06V300a9aMjRs3cuHCBbZv387AgQM5deoUrVq1+tc3kHl6egL/l7TezPWE9VZ1c5sAi+RXSmxFRGyAk5MTtWrVYvLkycyePZuMjAy++OKLm57To0cPfvrpJ3bt2sWff/7JmjVr6Nq1K3Z2D8avBmdnZ9q2bcvKlSu5evUq//vf/4iNjTVna68bMmQIx44dY8qUKbi4uPD6668TGhrKwYMHc92Xm5sbjz/+OLNmzeK1117j/PnzrF+//l/FX758eeDas4ZvxcvLC39/f7777rub1vvuu+8oXry4mTSLiLUH438vERG5a64vG0hOTr5pvfDwcHx9fVm4cCErV64kLS3N6kYnX19fPD09zacP3EhgYCAJCQnZjv/www9mOfzf0oXb0aVLF37//Xeio6P54osvMAwjW2ILUKpUKV566SU2bdrEkSNHuHLlCtOnT7/t/iD343crzZs3x97ens8++yxX9Vu1asXJkyfZuXNnjuU7duwgMTGRVq1a/au4RGyZElsRkYfU1q1bMQwj2/F169YB5Lg84O8cHBzo2rUrS5cuJSoqisqVK1OlShWz3M7OjrZt2/Lll1/m+Ias6323aNGCvXv3snv3brPs0qVLfPTRRwQFBVGhQgUAChQoAMCFCxdyfY1hYWEUKlSIJUuWsGTJEmrXrk1wcLBZnpaWxuXLl63OKVWqFB4eHqSnp9+07ejo6ByP53b8biUgIIB+/fqxadOmHN8El5WVxfTp0/nll1+Aa8+8dXV15b///S/nzp2zqvvHH3/Qv39/3NzcGD58+L+KS8SW6XFfIiIPqeeff560tDTatWtH+fLluXLlCrt27WLJkiXmK1tvpUePHsycOZOtW7fy5ptvZiufPHkymzZtokGDBjz77LOEhoaSnJzMF198wc6dO/H29mbkyJEsWrSI5s2bM3jwYAoVKsT8+fM5efIky5cvN5c2lCpVCm9vbz788EM8PDwoUKAAderUsUpU/8nR0ZH27duzePFiLl26xLRp06zKjx07RpMmTejcuTMVKlTAwcGBlStXcubMGZ566qmbXnubNm0IDg6mdevWlCpVikuXLrFlyxa+/PJLatWqRevWra3q79+/n4kTJ2Zrp2HDhlY3zv3d9OnTOXHiBIMHD2bFihW0atWKggULkpSUxBdffMEPP/xgxlmmTBnmz59Pt27dqFy5crY3j/3+++8sWrSIUqVK3fS6RPK1PH4qg4iI3KH169cbvXv3NsqXL2+4u7sbTk5ORunSpY3nn3/eOHPmjFXdfz7u6+8qVqxo2NnZGb/88kuO5adOnTJ69Ohh+Pr6Gs7OzkZISIgxcOBAIz093axz4sQJo2PHjoa3t7fh4uJi1K5d21i7dm22tlavXm1UqFDBcHBwyPWjvzZv3mwAhsViMX7++Werst9//90YOHCgUb58eaNAgQKGl5eXUadOHWPp0qW3bHfRokXGU089ZZQqVcpwdXU1XFxcjAoVKhivvvpqtsdpATfcJkyYYBhG9sd9XXf16lXj448/Nh5//HHDy8vLcHR0NAIDA41evXrl+Ciw7777zujatavh7+9vODo6Gn5+fkbXrl2Nw4cP3/R69LgvEcOwGEYOn2OJiEi+Ub16dQoVKnTDj+ZFRB4WWmMrIpKP7d+/n7i4OHr06JHXoYiI/GuasRURyYeOHDnCgQMHmD59Or///js//fQTLi4ueR2WiMi/ohlbEZF8aNmyZfTq1YuMjAwWLVqkpFZEbIJmbEVERETEJmjGVkRERERsghJbEREREbEJekGD5CtZWVn8+uuveHh43NHrPUVEROT+MwyDP//8k2LFipkvfcmJElvJV3799VcCAgLyOgwRERG5Az///DMlSpS4YbkSW8lXPDw8gGs/GJ6ennkcjYiIiORGSkoKAQEB5u/xG1FiK/nK9eUHnp6eSmxFREQeMrdaRqibx0RERETEJiixFRERERGboMRWRERERGyC1tiKiIhIvmYYBlevXiUzMzOvQ8m37O3tcXBw+NeP4lRiKyIiIvnWlStXSE5OJi0tLa9Dyffc3Nzw9/fHycnpjttQYisiIiL5UlZWFidPnsTe3p5ixYrh5OSkl/fkAcMwuHLlCr/99hsnT56kTJkyN30Jw80osRUREZF86cqVK2RlZREQEICbm1teh5Ovubq64ujoyKlTp7hy5QouLi531I5uHhMREZF87U5nB+XuuhvfB30nRURERMQmKLEVEREREZugNbYiIiIi//TLs/evrxIf3fUmLRYLK1eupG3btne97QeZZmxFREREHjK//fYbzz33HCVLlsTZ2Rk/Pz+aNWtGbGxsnsTTsGFDhgwZkid9/51mbEVEREQeMh06dODKlSvMnz+fkJAQzpw5Q3R0NOfOncvr0PKUElvJn/43GFLu/AHQd+QefNQkIiL5z4ULF9ixYwcxMTE0aNAAgMDAQGrXrp1j/caNG1OhQgVmzZplHvvtt98oXrw469evp0mTJqSnpzN69Gg+//xzzp49S0BAAKNGjaJPnz4AbNu2jeHDh3Po0CEKFSpEz549mThxIg4ODkRERLBt2za2bdvGu+++C8DJkycJCgq6twORAy1FEBEREXmIuLu74+7uzqpVq0hPT79l/b59+/L5559b1f3ss88oXrw4jRs3BqBHjx4sWrSImTNnEh8fz5w5c3B3dwfgf//7Hy1atKBWrVocOnSI2bNnM2/ePCZOnAjAu+++S926denXrx/JyckkJycTEBBwD6781pTYioiIiDxEHBwciIqKYv78+Xh7e1O/fn1eeeUVvvvuuxzrt2/fHoDVq1ebx6KiooiIiMBisXDs2DGWLl3KJ598Qrt27QgJCaFJkyZ06dIFgA8++ICAgABmzZpF+fLladu2LePGjWP69OlkZWXh5eWFk5MTbm5u+Pn54efnh729/b0fiBwosRURERF5yHTo0IFff/2VNWvWEB4eTkxMDDVq1CAqKipbXRcXF7p3784nn3wCwLfffsuRI0eIiIgAIC4uDnt7e3NZwz/Fx8dTt25dq9cN169fn9TUVH755Ze7fm3/hhJbERERkYeQi4sLTZs25fXXX2fXrl1EREQwZsyYHOv27duXzZs388svvxAZGUnjxo0JDAwErr3O1lYosRURERGxARUqVODSpUs5llWuXJmaNWsyd+5cPv/8c3r37m1VlpWVxbZt23I8NzQ0lN27d2MYhnksNjYWDw8PSpQoAYCTkxOZmZl38WrujBJbERERkYfIuXPnaNy4MZ999hnfffcdJ0+e5IsvvmDq1Km0adPmhuf17duXN954A8MwaNeunXk8KCiInj170rt3b1atWsXJkyeJiYlh6dKlAAwYMICff/6Z559/nh9++IHVq1czZswYhg4dip2dndnGnj17SExM5PfffycrK+veDsIN6HFfIiIiIv/0AD+i0d3dnTp16jBjxgxOnDhBRkYGAQEB9OvXj1deeeWG53Xt2pUhQ4bQtWtXXFxcrMpmz57NK6+8woABAzh37hwlS5Y02ypevDjr1q1j+PDhVK1alUKFCtGnTx9ee+018/xhw4bRs2dPKlSowF9//ZVnj/uyGH+fV5a7IigoiCFDhtyVN3BERERw4cIFVq1a9a/but/Gjh3LqlWriIuLy+tQTCkpKXh5efFknX44Otzn59hKjpbtnHXrSiIi98Dly5c5efIkwcHB2RI9W5SYmEipUqXYt28fNWrUyOtwsrnZ9+P67++LFy/i6el5wzby3VKE3bt3Y29vT8uWLfM6lFx59913c7zDMTcSExOxWCzmVqhQIRo0aMCOHTvubpBceyf1P5PvYcOGER0dfdf7EhERkdzLyMjg9OnTvPbaazz66KMPZFJ7t+S7xHbevHk8//zzbN++nV9//TWvw7klLy8vvL29/1UbW7ZsITk5me3bt1OsWDFatWrFmTNn7k6AN+Hu7o6Pj88970dERERuLDY2Fn9/f/bt28eHH36Y1+HcU/kqsU1NTWXJkiU899xztGzZMttMaExMDBaLhejoaGrWrImbmxv16tUjISHBrHPixAnatGlD0aJFcXd3p1atWmzZsuWGffbu3ZtWrVpZHcvIyKBIkSLMmzcPgGXLllG5cmVcXV3x8fEhLCzMvKsxIiKCtm3bmuferO6N+Pj44OfnR6VKlXjllVdISUlhz549Zvm2bduoXbs2zs7O+Pv7M3LkSK5evWqWBwUF8c4771i1Wa1aNcaOHWuWA7Rr1w6LxWLujx07lmrVqpnnXL+WadOm4e/vj4+PDwMHDiQjI8Osk56ezrBhwyhevDgFChSgTp06xMTEmOWnTp2idevWFCxYkAIFClCxYkXWrVt3w2tPT08nJSXFahMREclPGjZsiGEYJCQkULly5bwO557KV4nt0qVLKV++POXKleOZZ57hk08+Iaclxq+++irTp09n//79ODg4WD0SIzU1lRYtWhAdHc3BgwcJDw+ndevWJCUl5dhn37592bBhA8nJyeaxtWvXkpaWRpcuXUhOTqZr16707t2b+Ph4YmJiaN++fY5x3U7dnPz11198+umnwLXHcsCtX5OXG/v27QMgMjKS5ORkcz8nW7du5cSJE2zdupX58+cTFRVl9QfGoEGD2L17N4sXL+a7776jU6dOhIeHc/z4cQAGDhxIeno627dv5/Dhw7z5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7tT157yvWrXqth7feSMLFy7E3d2dAQMG5Fh+PSH9/PPPadq0qdWLquDaY0FffPFFjh49yqFDh/51PP+GElsRERGRh4iDgwNRUVHMnz8fb29v6tevzyuvvJLrG+H/6fjx44SEhGR71vw/HTt27IZPIrp+/NixY3cUw92ixFZERETkIdOhQwd+/fVX1qxZQ3h4ODExMdSoUSPHm7Ju5XaeI/CgP3NAia2IiIjIQ8jFxYWmTZvy+uuvs2vXLiIiIhgzZsxtt1O2bFl++umnW75VtGzZssTHx+dYdv142bJlb7v/u0mJrYiIiIgNqFChApcuXbrt855++mlSU1P54IMPciy/fvPYU089xZYtW7Kto83KymLGjBlUqFAh2/rb+0236IuIiIg8RM6dO0enTp3o3bs3VapUwcPDg/379zN16lTatGlj1vvf//5HXFyc1bmBgYHZ2qtTpw4jRowwX47Url07ihUrxo8//siHH37IY489xgsvvMCLL77I6tWrad26NdOnT6dOnTqcOXOGyZMnEx8fz5YtW7BYLPf68m9Kia2IiIjIPzzIbwNzd3enTp06zJgxgxMnTpCRkUFAQAD9+vXjlVdeMetNmzaNadOmWZ27YMECHnvssWxtvvnmmzzyyCO8//77fPjhh2RlZVGqVCk6duxIz549gWtLH77++msmT57MK6+8YvWChm+++YZKlSrd2wvPBb15TPIVvXlMRESuu9mbruT+05vHRERERET+PyW2IiIiImITlNiKiIiIiE1QYisiIiIiNkGJrYiIiORruo/+wXA3vg9KbEVERCRfcnR0BCAtLS2PIxH4v+/D9e/LndBzbEVERCRfsre3x9vbm7NnzwLg5uaW5y8YyI8MwyAtLY2zZ8/i7e2Nvb39HbelxFZERETyLT8/PwAzuZW84+3tbX4/7pQSWxEREcm3LBYL/v7+FClShIyMjLwOJ99ydHT8VzO11ymxFRERkXzP3t7+riRWkreU2EqOYmJiaNSoEefPn8fb2zuvwwEgIiKCCxcusGrVqn/dVvf/DMPRwemmdR7k94SLiIhIdnoqwgMoIiICi8Vibj4+PoSHh/Pdd9/ldWgiIiIiDywltg+o8PBwkpOTSU5OJjo6GgcHB1q1apXXYeWJzMxMsrKy8joMERERecApsX1AOTs74+fnh5+fH9WqVWPkyJH8/PPP/PbbbwD8/PPPdO7cGW9vbwoVKkSbNm1ITEw0z4+IiKBt27ZMmzYNf39/fHx8GDhwoNXC+PT0dF5++WUCAgJwdnamdOnSzJs3zyqOAwcOULNmTdzc3KhXrx4JCQlm2dixY6lWrRqffPIJJUuWxN3dnQEDBpCZmcnUqVPx8/OjSJEiTJo0yarNt99+m8qVK1OgQAECAgIYMGAAqampZnlUVBTe3t6sWbOGChUq4OzsTFJSUrYx2rdvH76+vrz55ps3HMf09HRSUlKsNhEREbFNSmwfAqmpqXz22WeULl0aHx8fMjIyaNasGR4eHuzYsYPY2Fjc3d0JDw/nypUr5nlbt27lxIkTbN26lfnz5xMVFUVUVJRZ3qNHDxYtWsTMmTOJj49nzpw5uLu7W/X96quvMn36dPbv34+DgwO9e/e2Kj9x4gTr169nw4YNLFq0iHnz5tGyZUt++eUXtm3bxptvvslrr73Gnj17zHPs7OyYOXMm33//PfPnz+frr79mxIgRVu2mpaXx5ptv8vHHH/P9999TpEgRq/Kvv/6apk2bMmnSJF5++eUbjt2UKVPw8vIyt4CAgFyPu4iIiDxcdPPYA2rt2rVmknnp0iX8/f1Zu3YtdnZ2fP7552RlZfHxxx+bD5KOjIzE29ubmJgY/vOf/wBQsGBBZs2ahb29PeXLl6dly5ZER0fTr18/jh07xtKlS9m8eTNhYWEAhISEZItj0qRJNGjQAICRI0fSsmVLLl++jIuLCwBZWVl88skneHh4UKFCBRo1akRCQgLr1q3Dzs6OcuXK8eabb7J161bq1KkDwJAhQ8z2g4KCmDhxIv379+eDDz4wj2dkZPDBBx9QtWrVbDGtXLmSHj168PHHH9OlS5ebjuOoUaMYOnSouZ+SkqLkVkRExEYpsX1ANWrUiNmzZwNw/vx5PvjgA5o3b87evXs5dOgQP/74Ix4eHlbnXL58mRMnTpj7FStWtHp0ib+/P4cPHwYgLi4Oe3t7M2m9kSpVqlidD9ceYl2yZEngWmL69ziKFi2Kvb09dnZ2Vsf+/uDrLVu2MGXKFH744QdSUlK4evUqly9fJi0tDTc3NwCcnJys+r5uz549rF27lmXLltG2bdubxg7XlnQ4Ozvfsp6IiIg8/JTYPqAKFChA6dKlzf2PP/4YLy8v5s6dS2pqKo888ggLFy7Mdp6vr6/59T/ftWyxWMybsFxdXXMVx9/buD47/PcbuXLq42b9JiYm0qpVK5577jkmTZpEoUKF2LlzJ3369OHKlStmYuvq6prjaw1LlSqFj48Pn3zyCS1btvxX75MWERER26LE9iFhsViws7Pjr7/+okaNGixZsoQiRYrg6el5R+1VrlyZrKwstm3bZi5FuB8OHDhAVlYW06dPN2d1ly5dmuvzCxcuzIoVK2jYsCGdO3dm6dKld5TcLtg07Y7HTkRERB5MunnsAZWens7p06c5ffo08fHxPP/886SmptK6dWu6detG4cKFadOmDTt27ODkyZPExMQwePBgfvnll1y1HxQURM+ePenduzerVq0y27idJPNOlC5dmoyMDN577z1++uknFixYwIcffnhbbRQpUoSvv/6aH374ga5du3L16tV7FK2IiIg8TJTYPqA2bNiAv78//v7+1KlTh3379vHFF1/QsGFD3Nzc2L59OyVLlqR9+/aEhobSp08fLl++fFuzkLNnz6Zjx44MGDCA8uXL069fPy5dunQPrwqqVq3K22+/zZtvvkmlSpVYuHAhU6ZMue12/Pz8+Prrrzl8+DDdunUjMzPzHkQrIiIiDxOLYRhGXgchcr+kpKTg5eXFxYsXtRRBRETkIZHb39+asRURERERm6DEVkRERERsghJbEREREbEJSmxFRERExCYosRURERERm6DEVkRERERsghJbEREREbEJSmxFRERExCYosRURERERm6DEVkRERERsghJbEREREbEJSmxFRERExCYosRURERERm6DEVkRERERsghJbEREREbEJSmxFRERExCYosRURERERm6DEVkRERERsghJbEREREbEJSmxFRERExCYosb0DY8eOpVq1avelr4iICNq2bXtf+nrYJCYmYrFYiIuLy+tQRERE5AGgxBbYvXs39vb2tGzZMs9iuFGS9u677xIVFXXP+09JSeHVV1+lfPnyuLi44OfnR1hYGCtWrMAwjLvWjxJ1ERERuVcc8jqAB8G8efN4/vnnmTdvHr/++ivFihXL65BMXl5e97yPCxcu8Nhjj3Hx4kUmTpxIrVq1cHBwYNu2bYwYMYLGjRvj7e19z+P4u4yMDBwdHe9rnyIiIvJwy/cztqmpqSxZsoTnnnuOli1b5jg7+sYbb1C0aFE8PDzo06cPly9ftirft28fTZs2pXDhwnh5edGgQQO+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atWKHj16AFC6dGkyMjJ47733aN26NbGxsXz44YdW7QQFBZGamkp0dDRVq1bFzc2NkiVL4uTkxHvvvUf//v05cuTILZ/zumDBAnx8fOjcubPVUgiAFi1aMG/evFwntmXKlDGfypCSksLw4cNxdXW95Xl9+/Zl0KBBFChQgHbt2pnH165dy08//cQTTzxBwYIFWbduHVlZWZQrVy5bG7dTV0RERPIXLUW4RzZs2IC/vz9BQUGEh4ezdetWZs6cyerVq7G3twegatWqvP3227z55ptUqlSJhQsXMmXKFKt26tWrR//+/enSpQu+vr5MnToVX19foqKi+OKLL6hQoQJvvPEG06ZNu2k8n3zyCe3atcuW1AJ06NCBNWvW3HLW9bp58+Zx/vx5atSoQffu3Rk8eDBFihS55Xldu3bFwcGBrl274uLiYh739vZmxYoVNG7cmNDQUD788EMWLVpkNbN8J3VFREQkf7EYf188KXIPJSYmUqpUKfbt20eNGjXyJIaUlBS8vLy4ePGiliKIiIg8JHL7+1tLEeSey8jI4Ny5c7z22ms8+uijeZbUioiIiG3TUgS552JjY/H392ffvn3Z1hCLiIiI3C2asZV7rmHDhmjFi4iIiNxrmrEVEREREZugxFZEREREbIISWxERERGxCUpsRURERMQmKLEVEREREZugxFZEREREbIISWxERERGxCUpsRURERMQmKLEVEREREZugxFZEREREbIISWxERERGxCUpsRURERMQmKLEVEREREZugxFZEREREbIISWxERERGxCUpsRURERMQmKLEVEREREZvgkNcByIOhYcOGVKtWjXfeeQeAoKAghgwZwpAhQ+56XzExMTRq1Ijz58/j7e1919vPje7/GYajg9NN6yzbOes+RSMiIiJ3g2Zs85mIiAgsFku2berUqUyYMOGG51ksFlatWnVXYqhXrx7Jycl4eXndlfZEREREQDO2+VJ4eDiRkZFWx3x9fbG3t7/nfWdkZODk5ISfn98970tERETyF83Y5kPOzs74+flZbU2aNLnhsoOgoCAA2rVrh8ViMfcBVq9eTY0aNXBxcSEkJIRx48Zx9epVs9xisTB79myefPJJChQowKRJk4iJicFisXDhwgUAoqKi8Pb2ZuPGjYSGhuLu7k54eDjJyclmO1evXmXw4MF4e3vj4+PDyy+/TM+ePWnbtu1NrzU9PZ2UlBSrTURERGyTElu5pX379gEQGRlJcnKyub9jxw569OjBCy+8wNGjR5kzZw5RUVFMmjTJ6vyxY8fSrl07Dh8+TO/evXPsIy0tjWnTprFgwQK2b99OUlISw4YNM8vffPNNFi5cSGRkJLGxsaSkpORqacSUKVPw8vIyt4CAgDscBREREXnQKbHNh9auXYu7u7u5derU6ab1fX19AfD29sbPz8/cHzduHCNHjqRnz56EhITQtGlTJkyYwJw5c6zOf/rpp+nVqxchISGULFkyxz4yMjL48MMPqVmzJjVq1GDQoEFER0eb5e+99x6jRo2iXbt2lC9fnlmzZuXqxrNRo0Zx8eJFc/v5559veY6IiIg8nLTGNh9q1KgRs2fPNvcLFChA165db7udQ4cOERsbazVDm5mZyeXLl0lLS8PNzQ2AmjVr3rItNzc3SpUqZe77+/tz9uxZAC5evMiZM2eoXbu2WW5vb88jjzxCVlbWTdt1dnbG2dn5tq5LREREHk5KbPOhAgUKULp06X/dTmpqKuPGjaN9+/bZylxcXKz6uxVHR0erfYvFgmEY/zpGERERyT+U2EquODo6kpmZaXWsRo0aJCQk3JUk+Wa8vLwoWrQo+/bt44knngCuzQx/++23VKtW7Y7aXLBpGp6enncxShEREclrSmwlV4KCgoiOjqZ+/fo4OztTsGBBRo8eTatWrShZsiQdO3bEzs6OQ4cOceTIESZOnHhX+3/++eeZMmUKpUuXpnz58rz33nucP38ei8VyV/sRERGRh5duHpNcmT59Ops3byYgIIDq1asD0KxZM9auXcumTZuoVasWjz76KDNmzCAwMPCu9//yyy/TtWtXevToQd26dXF3d6dZs2ZWSx5EREQkf7MYWsgoD6GsrCxCQ0Pp3LnzTd+Y9k8pKSl4eXlx8eJFLUUQERF5SOT297eWIshD4dSpU2zatIkGDRqQnp7OrFmzOHnyJE8//XRehyYiIiIPCC1FkIeCnZ0dUVFR1KpVi/r163P48GG2bNlCaGhoXocmIiIiDwjN2MpDISAggNjY2LwOQ0RERB5gmrEVEREREZugxFZEREREbIISWxERERGxCUpsRURERMQmKLEVEREREZugxFZEREREbIISWxERERGxCUpsRURERMQmKLEVEREREZugxFZEREREbIISWxERERGxCUps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/fvTtGnTvA5HRERE5LYpsRXg2uttRURERB5mNn3zmIiIiIjkH0psRURERMQmKLEVEREREZugxFZEREREbIISWxERERGxCUpsRURERMQmKLEVEREREZugxFZEREREbIISWxERERGxCXrzmORP/xsMKU73t88SH93f/kRERPIZzdiKiIiIiE1QYisiIiIiNkGJrYiIiIjYBCW2IiIiImITlNiKiIiIiE1QYisiIiIiNkGJrYiIiIjYBD3H9l8aO3Ysq1atIi4u7p60n5iYSHBwMAcPHqRatWr3pI97yWKxsHLlStq2bZvXoVjp3ssJR4f7/BxbBt3n/kTy3rKds/I6BBHJR2xixva3337jueeeo2TJkjg7O+Pn50ezZs2IjY29q/1YLBZWrVp1V9u8lYCAAJKTk6lUqdIdnR8REYHFYsFiseDo6EhwcDAjRozg8uXLdzXOsWPH5ph4Jycn07x587val4iIiEhObGLGtkOHDly5coX58+cTEhLCmTNniI6O5ty5c3kd2r9mb2+Pn5/fv2ojPDycyMhIMjIyOHDgAD179sRisfDmm2/epShv7N/GLiIiIpJbD/2M7YULF9ixYwdvvvkmjRo1IjAwkNq1azNq1CiefPJJAHr37k2rVq2szsvIyKBIkSLMmzcPgIYNGzJ48GBGjBhBoUKF8PPzY+zYsWb9oKAgANq1a4fFYjH3r1uwYAFBQUF4eXnx1FNP8eeff5plWVlZTJkyheDgYFxdXalatSrLli0zy8+fP0+3bt3w9fXF1dWVMmXKEBkZCVxbimCxWMylDjereyPXZ7EDAgJo27YtYWFhbN682SxPT09n8ODBFClSBBcXFx577DH27dtnlkdFReHt7W3V5qpVq7BYLGb5uHHjOHTokDk7HBUVBVjPcl+/lhUrVtCoUSPc3NyoWrUqu3fvtmp7586dPP7447i6uhIQEMDgwYO5dOmSWf7BBx9QpkwZXFxcKFq0KB07drzhtaenp5OSkmK1iYiIiG166BNbd3d33N3dWbVqFenp6TnW6du3Lxs2bCA5Odk8tnbtWtLS0ujSpYt5bP78+RQoUIA9e/YwdepUxo8fbyaA1xO9yMhIkpOTrRK/EydOsGrVKtauXcvatWvZtm0bb7zxhlk+ZcoUPv30Uz788EO+//57XnzxRZ555hm2bdsGwOuvv87Ro0dZv3498fHx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a5EiRXB1dWXDhg2cOXMmx5nt3AgLC6Nu3bq0bduWTZs2kZiYyK5du3j11VfZv38/f/31F4MGDSImJoZTp04RGxvLvn37CA0NvaP+RERExHYosb0NISEhbN++nR9++IGwsDDq1KnD0qVL+eKLLwgPDzfr9evXj3LlylGzZk18fX2zzYbmRocOHQgPD6dRo0b4+vqyaNEisywsLAx/f3+aNWtGsWLF7uhaBg0aRHx8PF988QU1atRg6dKlLF68mEqVKjF69GjGjx9vdePY9OnTCQgI4PHHH+fpp59m2LBhuLm5meUODg7MnDmTOXPmUKxYMdq0aXNHcVksFtatW8cTTzxBr169KFu2LE899RSnTp2iaNGi2Nvbc+7cOXr06EHZsmXp3LkzzZs315MPREREBIvxz4WT8sBLTU2lePHiREZG0r59+7wO56GSkpKCl5cXFy9e1FIEERGRh0Ruf39rje1DJCsri99//53p06fj7e3Nk08+mdchiYiIiDwwlNg+RJKSkggODqZEiRJERUXd8PW8IiIiIvmRMqOHSFBQULZHbomIiIjINbp5TERERERsghJbEREREbEJSmxFRERExCYosRURERERm6DEVkRERERsghJbEREREbEJSmxFRERExCYosRURERERm6DEVkRERERsgt48JvnK9Te3paSk5HEkIiIiklvXf2/f6g2sSmwlXzl37hwAAQEBeRyJiIiI3K4///wTLy+vG5YrsZV8pVChQgAkJSXd9AdDciclJYWAgAB+/vlnPD098zqch57G8+7SeN5dGs+7S+N5ewzD4M8//6RYsWI3rafEVvIVO7try8q9vLz0H8ld5OnpqfG8izSed5fG8+7SeN5dGs/cy82ElG4eExERERGboMRWRERERGyCElvJV5ydnRkzZgzOzs55HYpN0HjeXRrPu0vjeXdpPO8ujee9YTFu9dwEEREREZGHgGZsRURERMQmKLEVEREREZugxFZEREREbIISWxERERGxCUpsRURERMQmKLGVfOP9998nKCgIFxcX6tSpw969e/M6pIfC2LFjsVgsVlv58uXN8suXLzNw4EB8fHxwd3enQ4cOnDlzJg8jfrBs376d1q1bU6xYMSwWC6tWrbIqNwyD0aNH4+/vj6urK2FhYRw/ftyqzh9//EG3bt3w9PTE29ubPn36kJqaeh+v4sFxq/GM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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "color_yellow = \"#FFE365\"\n", + "color_blue = \"#4483B5\"\n", + "color_purple = \"#533B6B\"\n", + "\n", + "slicot_full_names = {\n", + " \"a\": \"Analysis Routines\",\n", + " \"b\": \"Benchmark\",\n", + " \"c\": \"Adaptive Control\",\n", + " \"d\": \"Data Analysis\",\n", + " \"f\": \"Filtering\",\n", + " \"i\": \"Identification\",\n", + " \"m\": \"Mathematical routines\",\n", + " \"n\": \"Nonlinear Systems\",\n", + " \"s\": \"Synthesis Routines\",\n", + " \"t\": \"Transformation Routines\",\n", + " \"u\": \"Utility Routines\",\n", + "}\n", + "\n", + "def count_methods(list_routines, keys):\n", + " d = {key: 0 for key in keys}\n", + " for w in list_routines:\n", + " if w:\n", + " if w[0] in d:\n", + " d[w[0]] = d[w[0]] + 1\n", + " else:\n", + " d[w[0]] = 1\n", + " return d\n", + "\n", + "slicot_routines_dict = count_methods(slicot_routines, keys=slicot_full_names.keys())\n", + "slycot_routines_dict = count_methods(slycot_routines, keys=slicot_full_names.keys())\n", + "\n", + "df = pd.DataFrame(\n", + " {\n", + " \"chapter name\": slicot_full_names.values(),\n", + " \"slycot routines\": slycot_routines_dict.values(),\n", + " \"slicot routines\": slicot_routines_dict.values(),\n", + " },\n", + " index=slicot_routines_dict.keys()\n", + ")\n", + "csum = df.sum()\n", + "df.loc['total']= df.sum()\n", + "df.loc[df.index[-1], 'chapter name'] = '-'\n", + "display(df)\n", + "\n", + "names_sli = list(slicot_routines_dict.keys())\n", + "names_sli.reverse()\n", + "values_sli = list(slicot_routines_dict.values())\n", + "values_sli.reverse()\n", + "\n", + "names_sly = list(slycot_routines_dict.keys())\n", + "names_sly.reverse()\n", + "values_sly = list(slycot_routines_dict.values())\n", + "values_sly.reverse()\n", + "\n", + "height = 0.25\n", + "plt.barh(np.arange(len(slycot_routines_dict)), values_sly, height=height, color=color_yellow)\n", + "plt.barh(np.arange(len(slicot_routines_dict)) - height, values_sli, height=height, color=color_purple)\n", + "plt.yticks(np.arange(len(slicot_routines_dict)) - height, [slicot_full_names[x] for x in names_sli])\n", + "plt.legend((\"Slycot\",\"SLICOT\"))\n", + "plt.title(\"Slycot vs SLICOT\")\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "venn2(subsets = (len(set(slycot_routines)), len(set(slicot_routines)), len(intersection)), \n", + " set_labels = ('Slycot', 'SLICOT'),\n", + " set_colors=(color_yellow, color_purple),\n", + " alpha=0.8)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.12" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/doc/source/explanation/inspect_slycot.ipynb b/doc/source/explanation/inspect_slycot.ipynb new file mode 100644 index 00000000..278bb07e --- /dev/null +++ b/doc/source/explanation/inspect_slycot.ipynb @@ -0,0 +1,358 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Inspect Slycot" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook shows how to inspect the slycot module.\n", + "The result gives us a first insight which slicot procedures are implemented.\n", + "In addition we get some insight about the organization of the slycot module." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.5.5.dev84+g9815526\n" + ] + } + ], + "source": [ + "import re\n", + "import slycot\n", + "print(slycot.__version__)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Helper functions" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "def print_list_chunks(routines_list, n=6):\n", + " \"\"\"Print list in chunks of lists.\"\"\"\n", + " start = 0\n", + " end = len(routines_list)\n", + " step = n\n", + " for i in range(start, end, step):\n", + " x = i\n", + " print(routines_list[x:x+step])" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "def get_slycot_routines(sly):\n", + " all_attributes = dir(sly)\n", + " r = re.compile(\"[a-z][a-z][0-9][0-9a-z][a-z][a-z]\")\n", + " matched_attributes = list(filter(r.match, all_attributes)) # Read Note below\n", + " return matched_attributes" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Inspect Wrapper function" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Outer wrapper" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "There are currently 56 routines that are found in slycot.\n", + "------\n", + "['ab01nd', 'ab04md', 'ab05md', 'ab05nd', 'ab07nd', 'ab08nd']\n", + "['ab08nz', 'ab09ad', 'ab09ax', 'ab09bd', 'ab09md', 'ab09nd']\n", + "['ab13bd', 'ab13dd', 'ab13ed', 'ab13fd', 'ab13md', 'ag08bd']\n", + "['mb02ed', 'mb03rd', 'mb03vd', 'mb03vy', 'mb03wd', 'mb05md']\n", + "['mb05nd', 'mc01td', 'sb01bd', 'sb02md', 'sb02mt', 'sb02od']\n", + "['sb03md', 'sb03md57', 'sb03od', 'sb04md', 'sb04qd', 'sb10ad']\n", + "['sb10dd', 'sb10fd', 'sb10hd', 'sb10jd', 'sb10yd', 'sg02ad']\n", + "['sg03ad', 'sg03bd', 'tb01id', 'tb01pd', 'tb03ad', 'tb04ad']\n", + "['tb05ad', 'tc01od', 'tc04ad', 'td04ad', 'tf01md', 'tf01rd']\n", + "['tg01ad', 'tg01fd']\n", + "None\n" + ] + } + ], + "source": [ + "slycot_wrapper = get_slycot_routines(slycot)\n", + "\n", + "print(f\"There are currently {len(slycot_wrapper)} routines that are found in slycot.\")\n", + "print(\"------\")\n", + "print(print_list_chunks(slycot_wrapper))" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Inner wrapper" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "There are currently 74 routines that are found in slycot._wrapper.\n", + "------\n", + "['ab01nd', 'ab04md', 'ab05md', 'ab05nd', 'ab07nd', 'ab08nd']\n", + "['ab08nz', 'ab09ad', 'ab09ax', 'ab09bd', 'ab09md', 'ab09nd']\n", + "['ab13bd', 'ab13dd', 'ab13ed', 'ab13fd', 'ab13md', 'ag08bd']\n", + "['mb02ed', 'mb03rd', 'mb03vd', 'mb03vy', 'mb03wd', 'mb05md']\n", + "['mb05nd', 'mc01td', 'sb01bd', 'sb02md', 'sb02mt_c', 'sb02mt_cl']\n", + "['sb02mt_n', 'sb02mt_nl', 'sb02od_b', 'sb02od_c', 'sb02od_d', 'sb02od_n']\n", + "['sb03md', 'sb03od', 'sb04md', 'sb04qd', 'sb10ad', 'sb10dd']\n", + "['sb10fd', 'sb10hd', 'sb10jd', 'sb10yd', 'sg02ad_bb', 'sg02ad_bc']\n", + "['sg02ad_bd', 'sg02ad_bn', 'sg02ad_g', 'sg03ad', 'sg03bd', 'tb01id']\n", + "['tb01pd', 'tb03ad_l', 'tb03ad_r', 'tb04ad_c', 'tb04ad_r', 'tb05ad_ag']\n", + "['tb05ad_ng', 'tb05ad_nh', 'tc01od_l', 'tc01od_r', 'tc04ad_l', 'tc04ad_r']\n", + "['td04ad_c', 'td04ad_r', 'tf01md', 'tf01rd', 'tg01ad', 'tg01fd_ii']\n", + "['tg01fd_nn', 'tg01fd_uu']\n", + "None\n" + ] + } + ], + "source": [ + "slycot_f2py_wrapper = get_slycot_routines(slycot._wrapper)\n", + "\n", + "print(f\"There are currently {len(slycot_f2py_wrapper)} routines that are found in slycot._wrapper.\")\n", + "print(\"------\")\n", + "print(print_list_chunks(slycot_f2py_wrapper))" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Generate Sets for the Venn-Diagramm" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "from matplotlib_venn import venn2" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "There are currently 11 routines that found in slycot not in slycot._wrapper.\n", + "------\n", + "['sb03md57', 'tg01fd', 'tc01od', 'td04ad', 'tb03ad', 'sb02mt']\n", + "['sg02ad', 'tb04ad', 'tc04ad', 'sb02od', 'tb05ad']\n", + "None\n", + "\n", + "\n", + "There are currently 29 routines that are found in slycot._wrapper not in slycot.\n", + "------\n", + "['tb04ad_r', 'tb05ad_ag', 'tg01fd_uu', 'sb02mt_nl', 'tc04ad_l', 'tb04ad_c']\n", + "['sb02od_n', 'tg01fd_ii', 'sb02od_d', 'sg02ad_bb', 'sb02od_c', 'sg02ad_g']\n", + "['td04ad_c', 'sb02mt_cl', 'td04ad_r', 'tg01fd_nn', 'sb02mt_n', 'tc01od_r']\n", + "['sg02ad_bn', 'sb02mt_c', 'sb02od_b', 'sg02ad_bd', 'tb05ad_ng', 'tb05ad_nh']\n", + "['tc04ad_r', 'tb03ad_l', 'tc01od_l', 'tb03ad_r', 'sg02ad_bc']\n", + "None\n", + "\n", + "\n" + ] + } + ], + "source": [ + "not_in_slycot_f2py_wrapper = list(set(slycot_wrapper) - set(slycot_f2py_wrapper))\n", + "not_in_slycot_f2py_wrapper\n", + "\n", + "print(f\"There are currently {len(not_in_slycot_f2py_wrapper)} routines that found in slycot not in slycot._wrapper.\")\n", + "print(\"------\")\n", + "print(print_list_chunks(not_in_slycot_f2py_wrapper))\n", + "print(\"\\n\")\n", + "\n", + "not_in_slycot_wrapper = list(set(slycot_f2py_wrapper) - set(slycot_wrapper))\n", + "not_in_slycot_wrapper\n", + "\n", + "print(f\"There are currently {len(not_in_slycot_wrapper)} routines that are found in slycot._wrapper not in slycot.\")\n", + "print(\"------\")\n", + "print(print_list_chunks(not_in_slycot_wrapper))\n", + "print(\"\\n\")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "There are currently 85 routines that are found in slycot or in slycot._wrapper. (union)\n", + "------\n", + "['tb04ad_r', 'sb10fd', 'ab13bd', 'tg01fd_ii', 'sb01bd', 'ab09ax']\n", + "['sb03od', 'tf01md', 'ab04md', 'ab05md', 'sg02ad_g', 'mb05md']\n", + "['tg01fd_nn', 'sb02od', 'sb03md57', 'tc01od_r', 'mc01td', 'sg02ad_bn']\n", + "['td04ad', 'sb02mt', 'tb05ad_ng', 'mb03vd', 'tb05ad_nh', 'tc04ad_r']\n", + "['sb10jd', 'sg03bd', 'ag08bd', 'mb05nd', 'tc01od_l', 'tb04ad']\n", + "['tc04ad', 'sg02ad_bc', 'ab08nz', 'ab13dd', 'ab13md', 'sb03md']\n", + "['sb04md', 'ab01nd', 'tb05ad_ag', 'tg01fd_uu', 'sb02mt_nl', 'ab09ad']\n", + "['tc04ad_l', 'tb04ad_c', 'sb02od_n', 'sb10ad', 'mb02ed', 'sb10yd']\n", + "['sg02ad', 'ab07nd', 'sb02od_d', 'ab09bd', 'sg02ad_bb', 'tb01id']\n", + "['tf01rd', 'ab05nd', 'sb02od_c', 'td04ad_c', 'tb03ad', 'sb10hd']\n", + "['ab08nd', 'sb02mt_cl', 'ab13fd', 'td04ad_r', 'tb05ad', 'sb02mt_n']\n", + "['tg01fd', 'sb04qd', 'sg03ad', 'ab09md', 'tb01pd', 'tc01od']\n", + "['ab09nd', 'sb10dd', 'mb03wd', 'mb03vy', 'ab13ed', 'sb02mt_c']\n", + "['sb02od_b', 'sg02ad_bd', 'tg01ad', 'tb03ad_l', 'mb03rd', 'tb03ad_r']\n", + "['sb02md']\n", + "None\n", + "\n", + "\n", + "There are currently 45 routines that are found in slycot and in slycot._wrapper. (intersection)\n", + "------\n", + "['ab08nz', 'ab13dd', 'ab13md', 'sb03md', 'sb04md', 'ab01nd']\n", + "['ab09ad', 'sb10fd', 'ab13bd', 'sb10ad', 'mb02ed', 'sb10yd']\n", + "['ab07nd', 'sb03od', 'sb01bd', 'ab09ax', 'ab09bd', 'tf01md']\n", + "['ab04md', 'tb01id', 'tf01rd', 'ab05md', 'ab05nd', 'sb10hd']\n", + "['ab08nd', 'ab13fd', 'mb05md', 'sb04qd', 'sg03ad', 'ab09md']\n", + "['mc01td', 'tb01pd', 'ab09nd', 'sb10dd', 'mb03wd', 'mb03vy']\n", + "['ab13ed', 'tg01ad', 'mb03vd', 'sb10jd', 'sg03bd', 'ag08bd']\n", + "['mb05nd', 'mb03rd', 'sb02md']\n", + "None\n", + "\n", + "\n" + ] + } + ], + "source": [ + "union = list(set(slycot_f2py_wrapper) | set(slycot_wrapper))\n", + "\n", + "print(f\"There are currently {len(union)} routines that are found in slycot or in slycot._wrapper. (union)\")\n", + "print(\"------\")\n", + "print(print_list_chunks(union))\n", + "print(\"\\n\")\n", + "\n", + "\n", + "intersection = list(set(slycot_f2py_wrapper) & set(slycot_wrapper))\n", + "intersection\n", + "\n", + "print(f\"There are currently {len(intersection)} routines that are found in slycot and in slycot._wrapper. (intersection)\")\n", + "print(\"------\")\n", + "print(print_list_chunks(intersection))\n", + "print(\"\\n\")" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "color_yellow = \"#FFE365\"\n", + "color_blue = \"#4483B5\"\n", + "color_purple = \"#533B6B\"\n", + "\n", + "venn2(subsets = (len(set(slycot_wrapper)), \n", + " len(set(slycot_f2py_wrapper)), \n", + " len(intersection)),\n", + " set_labels = ('slycot', 'slycot._wrapper'),\n", + " set_colors=(color_yellow, color_blue),\n", + " alpha=0.8)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.12" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/doc/source/explanation/slicot_routines.txt b/doc/source/explanation/slicot_routines.txt new file mode 100644 index 00000000..43bc7fe3 --- /dev/null +++ b/doc/source/explanation/slicot_routines.txt @@ -0,0 +1,607 @@ +mb01wd +tg01gd +ab13fd +sg03ay +mb01oe +mb02fd +tg01oa +dg01ny +sg03ax +fb01qd +ma02az +mc01md +md03by +tf01mx +ib01nd +mb02rz +mb04bp +tb01kd +ab09gd +ma02jz +ud01cd +ib01rd +nf01bx +mb02rd +ma02es +mb04iy +tg01id +mb01rd +mc01xd +mb04wr +sg03bs +mb03kc +ma02cd +tb04ad +md03bx +mb03vy +ab09cd +tf01nd +sb09md +sb03ot +mb04pu +mb04yd +mb02pd +mb04tu +mb02ud +ib01cd +mb04dp +tg01fz +sb04od +nf01ad +mb03qd +ab09bd +mb02jd +sb02mw +ma02ad +mb04dl +sb08ed +tb01uy +md03ba +ab05nd +mb03pd +sb02mx +sb04ow +ma02mz +mb02cy +ag08by +mb03bb +ab09cx +mb01kd +sb02sd +mb01xd +sb01md +mb02ny +sb02ox +sb10pd +ma01cd +tg01hd +mb02nd +sb02cx +sb04px +mb03qg +tg01hx +mb03ag +mc01py +mb03kb +mb04jd +tg01bd +tb03ay +ab13ed +sb03rd +ma02id +ma02md +sb03os +mb02cv +mb05oy +sb06nd +nf01bp +sb02od +mb03md +fb01vd +ma02iz +tb01ld +mb02sd +tb01nd +ud01md +mb02xd +mb02md +sg03br +mb04az +sb02ru +sb10qd +sg03bu +sb04qr +mb03lf +ma01ad +sb04rd +ma02gd +sb04ry +ab13ad +ab13md +nf01by +mb04nd +mb03yt +sg02cx +tg01hu +ab09kx +mb04hd +mb03gd +sb08cd +mb03od +sb04mr +mb02kd +ab09jx +ud01bd +fb01sd +mb03rd +ab07nd +mb03fd +sb03ou +mb03ya +mb01rh +sb08hd +ab08nw +ab07md +ab05qd +mb02qy +mb03id +ma02bd +ma02dd +mb04ed +sb03td +mb04tv +td04ad +tb01ud +tc01od +nf01bs +ma02oz +sg02nd +mb04ru +mc01rd +mb03bd +mb04tt +sb08ny +tg01ad +sb04qu +nf01bf +tg01qd +mc01td +mb04fp +mb03ud +mb3lzp +sb04nv +mb04qb +mb04wp +mc01sy +sb10dd +mb02sz +mb04kd +tb04bw +mb01ry +sb03mv +tb03ad +mb03gz +mb01ot +mb03be +tb01zd +ab04md +mb01os +sb03qx +mb04pb +nf01bu +mb04su +mc01od +sb16bd +mb02td +sg03ad +sb03qy +mb03xs +md03bb +mb04qc +mb03jd +sb01by +ab09nd +sb03md +mb04oy +mb05nd +ab08nx +mb01rb +dg01md +mb02wd +sb03ud +mb03py +mc01pd +ma02pz +ab09iy +ma02od +sb10td +tf01my +sb16cy +tg01oz +ab05pd +mb04cd +sb16ay +sb10hd +mb02gd +mc03md +mb03bc +sb04nx +mc01qd +ab01od +ab09jd +sb16ad +sg03bv +nf01bb +ab09dd +mb03lp +md03bf +mb03ah +mb3jzp +sb04mu +ab09kd +sb03ov +sb03pd +fd01ad +sb03sd +td05ad +mb02hd +mb02cd +mb03qx +sb04nd +mb04tb +sb04pd +tg01jy +tb04cd +tg01dd +ab09ed +mb03wx +tg01pd +tf01pd +sb08fd +ab13ax +nf01ba +sb08md +mb04dy +sb04my +ab09fd +mb04vd +mb01md +ib01oy +mb04ld +sb01bd +sb02mu +sg03bx +tg01ed +mb02qd +mb01ss +mb01rw +sb10ud +mb03cz +ag8byz +sb02ow +mb02dd +sb08nd +mb03my +mb03yd +tg01od +mc01sw +ma02bz +ib01ad +ab09hd +ud01mz +td03ad +sb03my +ib03bd +mb04dd +mb04xd +ma02hd +ab09ax +tg01hy +mc01sx +tb01ux +df01md +mb04vx +mb04wd +ab08md +tb01vd +nf01ay +md03bd +mb03rz +ab09ix +ab13dd +tb01iz +nf01bw +mb04qf +ab05sd +mb04db +mb03ai +sb08gd +mb02od +mb04ty +mb02uv +ib01px +tb01ty +sb03oy +sb03mu +tg01nd +ab09hx +ab09id +mb04id +mb03ed +mb04di +mb04tx +sb03od +mb04xy +mb03hz +tc04ad +mb01rx +sb02ov +mb03zd +mb03jp +mb02yd +mb04ox +bd01ad +mb04fd +ab05md +tb04bx +dg01od +sb10zd +mb01rt +sb02mr +ab01nd +mb04bz +ma01bz +ma02ed +mb03ld +tb01md +tb01xz +mb04qs +ab09md +sb10id +sb03sx +mb02cu +ab13bd +mb3oyz +mb02tz +tb01px +mb03iz +sg03bw +mb04dz +nf01bv +bd02ad +tf01md +mb03wd +mb4dbz +mb04tw +mb03vd +mb01oo +fb01rd +mb04rb +mb03ry +mb01xy +tb05ad +ib03ad +mb03xz +mb05md +mb02ed +sb03mw +sg03bd +mb01ru +mb01oc +bb02ad +ab09jw +mb03cd +mb04pa +sb10yd +mb02jx +tg01az +sg02ad +ma02hz +mb03dz +tg01md +sb08my +tb04ay +sb02nd +sb02mt +sb04rw +mb04wu +nf01be +de01pd +sb02mv +sb10ed +sb10zp +mb03lz +sb02oy +sb04md +mb03bg +mb03ad +mb01uw +sb10kd +ma02jd +ma02gz +tf01qd +mb03td +mb04gd +tb04bv +tg01ld +mb03ba +ue01md +mb3pyz +mb03xp +sb02ou +mb01nd +sg02cw +mb04yw +sb04mw +mb01uy +sg03by +ib01py +mb02uw +tg01ob +mb03jz +mb04ad +tg01fd +mb03sd +ab13id +ab08ny +mb03za +mb02uu +ab08nd +mc01wd +tg01ly +mb01uz +mb03xu +mb03nd +ag07bd +sg03bt +mb03xd +ma02nz +ab13dx +ab08nz +sb04ny +mb03ts +sb04qy +mb03rx +mb03af +ib01md +mb03ke +sb02pd +sb16cd +ab8nxz +mb04bd +tf01rd +mb01ux +mb03bz +sb03sy +mc03ny +sb10ld +ma02fd +td03ay +bb04ad +mb03ab +dk01md +ab05od +mc03nx +mb01td +tb01id +tg01cd +mb04ow +sb04nw +mb03ae +mb03rw +mb03qy +sb04py +nf01bq +mb03dd +tb01kx +mb01ud +ma01bd +mb03ny +ab08mz +sb02rd +sb04qd +tb01wx +ag08bz +tg01wd +tb04bd +sb02md +bb01ad +mc01sd +mc01vd +sb10ad +mb01vd +de01od +ib01pd +mb03bf +sb02ms +mb04py +mc03nd +tb01wd +mc01nd +dg01nd +ab09ad +mb02id +tb01yd +sb03mx +mb03vw +sg02cv +ab05rd +mb04ds +mb01od +mb4dpz +mb03oy +sb03qd +sb01bx +sb08dd +ib01od +sb10md +mb01ld +mb04iz +mb05od +tb01td +mb02vd +mb03fz +mb05my +mb01oh +mb04zd +sb03oz +tg01kz +mb02cx +tg01jd +mb01zd +mb01pd +sb01dd +mb03hd +sb02qd +mb03qw +tb01xd +ud01nd +sb10rd +ib01my +tf01od +ud01dd +tb01vy +ab09hy +sb04rx +ib01qd +mb04od +mb03qv +sg03bz +sb03or +mb03kd +ab13cd +tg01kd +mb03wa +mb04ts +mb03ka +mb4dlz +mb04qu +sb10fd +ma02pd +sb10jd +mb01qd +ab09jv +sb10vd +fb01td +ma02ez +tc05ad +sb10wd +md03ad +nf01bd +ma02cz +mb04ny +sb04rv +nf01br +tb01pd +ab01md +ib01bd +mb01yd +tg01nx +sb01fy +mb04md +sb10sd +mb04ud +mb01sd +ag08bd +ab09bx +bb03ad diff --git a/doc/source/guides/ab13dd_nb.ipynb b/doc/source/guides/ab13dd_nb.ipynb new file mode 100644 index 00000000..3a06ea94 --- /dev/null +++ b/doc/source/guides/ab13dd_nb.ipynb @@ -0,0 +1,210 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# ab13dd Example\n", + "\n", + "Johannes Kaisinger, 26 July 2023\n", + "\n", + "The `ab13dd` calculates the L-infinity norm of a state space system.\n", + "For a stable system it is equal to the H-infintiy norm." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create data" + ] + }, + { + "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_): system matrix\n", + " B (_type_): input matrix\n", + " C (_type_): output matrix\n", + " D (_type_): feedthrough matrix\n", + " gam_l (_type_): low bound for norm\n", + " gam_h (_type_): upper bound for norm\n", + " emin (_type_): min difference between gam_l and gam_h\n", + "\n", + " Returns:\n", + " float: norm\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/index.rst b/doc/source/guides/index.rst new file mode 100644 index 00000000..748b5cc5 --- /dev/null +++ b/doc/source/guides/index.rst @@ -0,0 +1,12 @@ +:orphan: + +Examples +======== + +The following notebooks show some use cases for Slycot. + +.. toctree:: + :maxdepth: 1 + + system_norms + sysid \ No newline at end of file diff --git a/doc/source/guides/sy10yd_nb.ipynb b/doc/source/guides/sy10yd_nb.ipynb new file mode 100644 index 00000000..ea669763 --- /dev/null +++ b/doc/source/guides/sy10yd_nb.ipynb @@ -0,0 +1,227 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# sy10yd Example\n", + "\n", + "Johannes Kaisinger, 04 April 2024\n", + "\n", + "The `sy10yd` fits a frequency response to a stable minimum phase SISO system.\n", + "This can be seen as a system identification approach." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create data" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "from scipy import signal \n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "import slycot" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "A = np.array([[0.0, 1.0], [-0.5, -0.1]])\n", + "B = np.array([[0.0], [1.0]])\n", + "C = np.array([[1.0, 0.0]])\n", + "D = np.zeros((1,1))\n", + "\n", + "sys_ss = signal.lti(A,B,C,D)\n", + "sys_tf = signal.ss2tf(A,B,C,D)\n", + "num, den = sys_tf\n" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "w, H = signal.freqs(num.squeeze(), den)\n", + "\n", + "real_H_resp = np.expand_dims(np.real(H), axis=(1))\n", + "imag_H_resp = np.expand_dims(np.imag(H), axis=(1))" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.semilogx(w, 20 * np.log10(abs(H)), label=\"H\")\n", + "plt.semilogx(w, 20 * np.log10(abs(np.real(H))), linestyle=\"dashed\", label=\"real part\")\n", + "plt.semilogx(w, 20 * np.log10(abs(np.imag(H))), linestyle=\"dashed\", label=\"imag part\")\n", + "plt.xlabel('Frequency')\n", + "plt.ylabel('Amplitude response [dB]')\n", + "plt.grid(True)\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "plt.semilogx(w, 20 * np.log10(abs(H)), 'r', label='H')\n", + "plt.semilogx(w, 20 * (np.log10(abs(np.sqrt(np.real(H)**2 + np.imag(H)**2))) ), 'b--', label='real and imag')\n", + "plt.xlabel('Frequency')\n", + "plt.ylabel('Amplitude response [dB]')\n", + "plt.grid(True)\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Systemidentification\n" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(2, 2)\n", + "(2, 1)\n", + "(1, 2)\n", + "(1, 1)\n" + ] + } + ], + "source": [ + "omega = w\n", + "n = 2\n", + "nid, Aid, Bid, Cid, Did = slycot.sb10yd(0, 0, len(omega), real_H_resp, imag_H_resp, omega, \n", + " n, tol=0)\n", + "\n", + "print(Aid.shape)\n", + "print(Bid.shape)\n", + "print(Cid.shape)\n", + "print(Did.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "max_rel_error = 0.24744541408298004\n", + "check_within_bounds = True\n" + ] + } + ], + "source": [ + "sys_tf_id = signal.ss2tf(Aid,Bid,Cid,Did)\n", + "num_id, den_id = sys_tf_id\n", + "w_id, H_id = signal.freqs(num_id.squeeze(), den_id, worN=w)\n", + "\n", + "max_rel_error = np.max((abs(H_id) - abs(H))/abs(H))\n", + "check_within_bounds = np.allclose(abs(H_id),abs(H),rtol=0.3,atol=0)\n", + "print(f\"{max_rel_error = }\")\n", + "print(f\"{check_within_bounds = }\")" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.semilogx(w, 20 * np.log10(abs(H)), label=\"sys\")\n", + "plt.semilogx(w_id, 20 * np.log10(abs(H_id)), label=\"ident\")\n", + "plt.xlabel('Frequency')\n", + "plt.ylabel('Amplitude response [dB]')\n", + "plt.grid(True)\n", + "plt.legend()\n", + "plt.show()" + ] + } + ], + "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.12" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/doc/source/guides/sysid.rst b/doc/source/guides/sysid.rst new file mode 100644 index 00000000..2960baff --- /dev/null +++ b/doc/source/guides/sysid.rst @@ -0,0 +1,10 @@ + +:orphan: + +System identification +===================== + +.. toctree:: + :maxdepth: 1 + + sy10yd_nb \ No newline at end of file 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/source/index.rst b/doc/source/index.rst new file mode 100644 index 00000000..3d5f3252 --- /dev/null +++ b/doc/source/index.rst @@ -0,0 +1,63 @@ +.. 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. + +Welcome to Slycot's documentation! +================================== + +Python wrapper for selected `SLICOT `_ routines, +notably including solvers for Riccati, Lyapunov, and Sylvester equations. + +Chapters +-------- + +The Slycot library is organised by chapters. Each chapter can be identified by a single letter. The following chapters are included: + +- ``A`` : Analysis Routines +- ``B`` : Benchmark +- ``C`` : Adaptive Control +- ``D`` : Data Analysis +- ``F`` : Filtering +- ``I`` : Identification +- ``M`` : Mathematical Routines +- ``N`` : Nonlinear Systems +- ``S`` : Synthesis Routines +- ``T`` : Transformation Routines +- ``U`` : Utility Routines + +.. toctree:: + :maxdepth: 2 + :hidden: + :caption: 🚀 Tutorials + + /tutorial/index + /tutorial/getting + +.. toctree:: + :maxdepth: 2 + :hidden: + :caption: 💡 Explanation + + /explanation/index + +.. toctree:: + :maxdepth: 2 + :hidden: + :caption: 🪄 How-to guides + + /guides/index + +.. toctree:: + :maxdepth: 2 + :hidden: + :caption: 📚 Reference + + /reference/index + +.. toctree:: + :maxdepth: 2 + :hidden: + :caption: Contributing + + /contributing/index diff --git a/doc/source/reference/index.rst b/doc/source/reference/index.rst new file mode 100644 index 00000000..ee1de2dd --- /dev/null +++ b/doc/source/reference/index.rst @@ -0,0 +1,26 @@ +.. 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. + +.. toctree:: + :maxdepth: 1 + + slycot_outer + +For advanced users and developer also the + +.. toctree:: + :maxdepth: 1 + + slycot_inner + +and the + +`SLICOT-Reference `_ + +can be important. \ No newline at end of file diff --git a/doc/source/reference/slycot_inner.rst b/doc/source/reference/slycot_inner.rst new file mode 100644 index 00000000..d9d54de8 --- /dev/null +++ b/doc/source/reference/slycot_inner.rst @@ -0,0 +1,112 @@ +.. _inner_function-ref: + +************************ +Inner function reference +************************ + +.. automodule:: slycot + :no-members: + :no-inherited-members: + :no-special-members: + +Analysis +======== + +.. autosummary:: + :toctree: generated/ + + _wrapper.ab01nd + _wrapper.ab04md + _wrapper.ab05md + _wrapper.ab05nd + _wrapper.ab07nd + _wrapper.ab08nd + _wrapper.ab08nz + _wrapper.ab09ad + _wrapper.ab09ax + _wrapper.ab09bd + _wrapper.ab09md + _wrapper.ab09nd + _wrapper.ab13bd + _wrapper.ab13dd + _wrapper.ab13ed + _wrapper.ab13fd + _wrapper.ab13md + _wrapper.ag08bd + +Mathematical routines +===================== + +.. autosummary:: + :toctree: generated/ + + _wrapper.mb02ed + _wrapper.mb03rd + _wrapper.mb03vd + _wrapper.mb03vy + _wrapper.mb03wd + _wrapper.mb05md + _wrapper.mb05nd + _wrapper.mc01td + +Synthesis +========= + +.. autosummary:: + :toctree: generated/ + + _wrapper.sb01bd + _wrapper.sb02md + _wrapper.sb02mt_c + _wrapper.sb02mt_cl + _wrapper.sb02mt_n + _wrapper.sb02mt_nl + _wrapper.sb02od_b + _wrapper.sb02od_c + _wrapper.sb02od_d + _wrapper.sb02od_n + _wrapper.sb03md + _wrapper.sb03od + _wrapper.sb04md + _wrapper.sb04qd + _wrapper.sb10ad + _wrapper.sb10dd + _wrapper.sb10fd + _wrapper.sb10hd + _wrapper.sb10jd + _wrapper.sb10yd + _wrapper.sg02ad_bb + _wrapper.sg02ad_bc + _wrapper.sg02ad_bd + _wrapper.sg02ad_bn + _wrapper.sg02ad_g + _wrapper.sg03ad + _wrapper.sg03bd + +Transformation Routines +======================= + +.. autosummary:: + :toctree: generated/ + + _wrapper.tb01id + _wrapper.tb01pd + _wrapper.tb03ad_l + _wrapper.tb03ad_r + _wrapper.tb04ad_c + _wrapper.tb04ad_r + _wrapper.tb05ad_ag + _wrapper.tb05ad_ng + _wrapper.tb05ad_nh + _wrapper.tc01od_l + _wrapper.tc01od_r + _wrapper.tc04ad_l + _wrapper.tc04ad_r + _wrapper.td04ad_c + _wrapper.td04ad_r + _wrapper.tf01md + _wrapper.tf01rd + _wrapper.tg01ad + _wrapper.tg01fd_ii + _wrapper.tg01fd_nn + _wrapper.tg01fd_uu \ No newline at end of file diff --git a/doc/source/reference/slycot_outer.rst b/doc/source/reference/slycot_outer.rst new file mode 100644 index 00000000..2fbd3b50 --- /dev/null +++ b/doc/source/reference/slycot_outer.rst @@ -0,0 +1,94 @@ +.. _function-ref: + +************************ +Outer function reference +************************ + +.. automodule:: slycot + :no-members: + :no-inherited-members: + :no-special-members: + +Analysis +======== + +.. autosummary:: + :toctree: generated/ + + ab01nd + ab04md + ab05md + ab05nd + ab07nd + ab08nd + ab08nz + ab09ad + ab09ax + ab09bd + ab09md + ab09nd + ab13bd + ab13dd + ab13ed + ab13fd + ab13md + ag08bd + +Mathematical routines +===================== + +.. autosummary:: + :toctree: generated/ + + mb02ed + mb03rd + mb03vd + mb03vy + mb03wd + mb05md + mb05nd + mc01td + +Synthesis +========= + +.. autosummary:: + :toctree: generated/ + + sb01bd + sb02md + sb02mt + sb02od + sb03md + sb03md57 + sb03od + sb04md + sb04qd + sb10ad + sb10dd + sb10fd + sb10hd + sb10jd + sb10yd + sg02ad + sg03ad + sg03bd + +Transformation Routines +======================= + +.. autosummary:: + :toctree: generated/ + + tb01id + tb01pd + tb03ad + tb04ad + tb05ad + tc01od + tc04ad + td04ad + tf01md + tf01rd + tg01ad + tg01fd \ 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/source/tutorial/index.rst b/doc/source/tutorial/index.rst new file mode 100644 index 00000000..b0df32b6 --- /dev/null +++ b/doc/source/tutorial/index.rst @@ -0,0 +1,47 @@ +.. this page is referenced from the front page but it's unnecessary as a navigation section for now. + +:orphan: + +Installation +============ + +The `slycot` package can be installed using conda or pip. The +package requires `NumPy `_. + +For users with the Anaconda distribution of Python, the following +command can be used:: + + conda install -c conda-forge slycot + +This installs `slycot` from conda-forge, including the +`openblas` package. NumPy will also be installed if +they are not already present. + +.. note:: + Mixing packages from conda-forge and the default conda channel + can sometimes cause problems with dependencies, so it is usually best to + instally NumPy, SciPy, and Matplotlib from conda-forge as well. + +To install using pip:: + + pip install slycot + +.. note:: + If you install Slycot using pip you'll need a development + environment (e.g., Python development files, C and Fortran compilers). + Pip installation can be particularly complicated for Windows. + +Users can check to insure that slycot is installed +correctly by running the command:: + + python -c "import slycot" + +and verifying that no error message appears. More information on the +Slycot package can be obtained from the `Slycot project page +`_. + +Alternatively, to install from source, first `download the source +`_ and unpack it. +To install in your home directory, use:: + + pip install . \ No newline at end of file diff --git a/examples/ab13dd_example.py b/examples/ab13dd_example.py new file mode 100644 index 00000000..33855de5 --- /dev/null +++ b/examples/ab13dd_example.py @@ -0,0 +1,25 @@ +# Enrico Avventi 2010 + +import numpy as np +import slycot + +A = np.array([[ 0 , 1 , 0 , 0 , 0 , 0 ], + [ -0.5 , -0.0002 , 0 , 0 , 0 , 0 ], + [ 0 , 0 , 0 , 1 , 0 , 0 ], + [ 0 , 0 , -1 , -0.00002 , 0 , 0 ], + [ 0 , 0 , 0 , 0 , 0 , 1 ], + [ 0 , 0 , 0 , 0 , -2 , -0.000002 ]]) +B = np.array([[ 1 ], + [ 0 ], + [ 1 ], + [ 0 ], + [ 1 ], + [ 0 ]]) +C = np.array([[ 1 , 0 , 1 , 0 , 1 , 0 ]]) +D = np.array([[ 0 ]]) +out = slycot.ab13dd('C', 'I', 'N', 'D', 6, 1, 1, A, np.eye(6), B, C, D) +print('--- Example for ab13dd ---') +print('The L_infty norm of the system is') +print(out[0]) +print('The peak frequency is') +print(out[1]) \ No newline at end of file diff --git a/examples/ab13dd_nb.ipynb b/examples/ab13dd_nb.ipynb new file mode 100644 index 00000000..84af663b --- /dev/null +++ b/examples/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 +}