Skip to content

Instantly share code, notes, and snippets.

@andportnoy
Created August 28, 2022 16:18
Show Gist options
  • Save andportnoy/03c70436a8b830f90e99ab22640057fb to your computer and use it in GitHub Desktop.
Save andportnoy/03c70436a8b830f90e99ab22640057fb to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "6e5acf15",
"metadata": {},
"source": [
"## `LinearOperator` + `svds`"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "fcf747e3",
"metadata": {},
"outputs": [],
"source": [
"import scipy as sp\n",
"import numpy as np\n",
"from collections import defaultdict\n",
"from tabulate import tabulate"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "ec038da9",
"metadata": {},
"outputs": [],
"source": [
"class VerboseLinearOperator(sp.sparse.linalg.LinearOperator):\n",
" def __init__(self, *args, **kwargs):\n",
" super().__init__(*args, **kwargs)\n",
" \n",
" def __getattribute__(self, attr):\n",
" callcounter[attr] += 1\n",
" return super().__getattribute__(attr)\n",
" \n",
" def _matvec(self, x):\n",
" return np.zeros((self.shape[0], 1))\n",
" \n",
" def _matmat(self, X):\n",
" return np.zeros((self.shape[0], X.shape[1]))\n",
" \n",
" def _rmatvec(self, x):\n",
" return np.zeros((self.shape[1], 1))\n",
" \n",
" def _rmatmat(self, X):\n",
" return np.zeros((self.shape[1], X.shape[1]))"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "0b9f1429",
"metadata": {},
"outputs": [],
"source": [
"vlo = VerboseLinearOperator(dtype=np.float32, shape=(10, 10))"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "c9ffe1af",
"metadata": {},
"outputs": [],
"source": [
"data = {}\n",
"for solver in ['arpack', 'lobpcg', 'propack']:\n",
" callcounter = defaultdict(lambda: 0)\n",
" U, S, Vt = sp.sparse.linalg.svds(vlo, k=2, solver=solver)\n",
" data[solver] = dict(U=U, S=S, Vt=Vt, callcounter=callcounter)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "8753501e",
"metadata": {},
"outputs": [],
"source": [
"methods = set()\n",
"for solver in data:\n",
" methods.update(data[solver]['callcounter'].keys())\n",
"methods = sorted(methods)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "35d2d20f",
"metadata": {},
"outputs": [],
"source": [
"values = [\n",
" [solver, data[solver]['U'].shape, data[solver]['S'].shape, data[solver]['Vt'].shape]\n",
" + [data[solver]['callcounter'][method] for method in methods]\n",
" for solver in data\n",
"]"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "8cb12ab7",
"metadata": {},
"outputs": [],
"source": [
"rownames = ['attribute'] + \\\n",
"['shape of ' + name for name in ['U', 'S', 'Vt']] + \\\n",
"['# calls to ' + name for name in methods]"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "953a171f",
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"text/html": [
"<table>\n",
"<thead>\n",
"<tr><th>attribute </th><th>arpack </th><th>lobpcg </th><th>propack </th></tr>\n",
"</thead>\n",
"<tbody>\n",
"<tr><td>shape of U </td><td>(10, 2) </td><td>(10, 2) </td><td>(10, 2) </td></tr>\n",
"<tr><td>shape of S </td><td>(2,) </td><td>(2,) </td><td>(2,) </td></tr>\n",
"<tr><td>shape of Vt </td><td>(2, 10) </td><td>(2, 10) </td><td>(2, 10) </td></tr>\n",
"<tr><td># calls to _matmat </td><td>0 </td><td>1 </td><td>0 </td></tr>\n",
"<tr><td># calls to _matvec </td><td>10 </td><td>0 </td><td>11 </td></tr>\n",
"<tr><td># calls to _rmatmat</td><td>1 </td><td>2 </td><td>0 </td></tr>\n",
"<tr><td># calls to _rmatvec</td><td>10 </td><td>0 </td><td>12 </td></tr>\n",
"<tr><td># calls to dtype </td><td>4 </td><td>4 </td><td>6 </td></tr>\n",
"<tr><td># calls to matmat </td><td>1 </td><td>1 </td><td>1 </td></tr>\n",
"<tr><td># calls to matvec </td><td>1 </td><td>1 </td><td>12 </td></tr>\n",
"<tr><td># calls to rmatmat </td><td>1 </td><td>1 </td><td>1 </td></tr>\n",
"<tr><td># calls to rmatvec </td><td>1 </td><td>1 </td><td>13 </td></tr>\n",
"<tr><td># calls to shape </td><td>47 </td><td>12 </td><td>52 </td></tr>\n",
"</tbody>\n",
"</table>"
],
"text/plain": [
"'<table>\\n<thead>\\n<tr><th>attribute </th><th>arpack </th><th>lobpcg </th><th>propack </th></tr>\\n</thead>\\n<tbody>\\n<tr><td>shape of U </td><td>(10, 2) </td><td>(10, 2) </td><td>(10, 2) </td></tr>\\n<tr><td>shape of S </td><td>(2,) </td><td>(2,) </td><td>(2,) </td></tr>\\n<tr><td>shape of Vt </td><td>(2, 10) </td><td>(2, 10) </td><td>(2, 10) </td></tr>\\n<tr><td># calls to _matmat </td><td>0 </td><td>1 </td><td>0 </td></tr>\\n<tr><td># calls to _matvec </td><td>10 </td><td>0 </td><td>11 </td></tr>\\n<tr><td># calls to _rmatmat</td><td>1 </td><td>2 </td><td>0 </td></tr>\\n<tr><td># calls to _rmatvec</td><td>10 </td><td>0 </td><td>12 </td></tr>\\n<tr><td># calls to dtype </td><td>4 </td><td>4 </td><td>6 </td></tr>\\n<tr><td># calls to matmat </td><td>1 </td><td>1 </td><td>1 </td></tr>\\n<tr><td># calls to matvec </td><td>1 </td><td>1 </td><td>12 </td></tr>\\n<tr><td># calls to rmatmat </td><td>1 </td><td>1 </td><td>1 </td></tr>\\n<tr><td># calls to rmatvec </td><td>1 </td><td>1 </td><td>13 </td></tr>\\n<tr><td># calls to shape </td><td>47 </td><td>12 </td><td>52 </td></tr>\\n</tbody>\\n</table>'"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tabulate(list(zip(rownames, *values)), headers='firstrow', tablefmt='html')"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment