https://github.com/goessl/adjugate
A package for calculating submatricies, minors, adjugate- and cofactor matrices.
https://github.com/goessl/adjugate
adjugate cofactor determinant inverse linear-algebra matrix minor numpy python submatrix
Last synced: 6 months ago
JSON representation
A package for calculating submatricies, minors, adjugate- and cofactor matrices.
- Host: GitHub
- URL: https://github.com/goessl/adjugate
- Owner: goessl
- License: mit
- Created: 2022-12-29T19:34:57.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-09-17T10:48:04.000Z (8 months ago)
- Last Synced: 2024-11-15T02:58:21.774Z (6 months ago)
- Topics: adjugate, cofactor, determinant, inverse, linear-algebra, matrix, minor, numpy, python, submatrix
- Language: Python
- Homepage:
- Size: 228 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.ipynb
- License: LICENSE
Awesome Lists containing this project
README
{
"cells": [
{
"cell_type": "markdown",
"id": "cf41ff61-26ac-4762-bc45-fa49deb0ce47",
"metadata": {},
"source": [
"# adjugate\n",
"\n",
"A package for calculating submatricies, minors, adjugate- and cofactor matricies."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "78c08248-d25f-4f15-ba1d-6a073c8f0f26",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(array([[0.46445212, 0.90776864, 0.5617845 , 0.46365445],\n",
" [0.23096052, 0.37817574, 0.19684724, 0.26416446],\n",
" [0.8157284 , 0.35109541, 0.29357478, 0.63978973],\n",
" [0.97616731, 0.71221494, 0.18073805, 0.7949908 ]]),\n",
" array([[ 0.04081465, -0.13855441, 0.00220198, 0.0204637 ],\n",
" [ 0.01427584, -0.02328107, -0.02248499, 0.01750541],\n",
" [ 0.01310092, -0.00671938, 0.02476545, -0.02533861],\n",
" [-0.06588407, 0.19251526, 0.01180968, -0.02407058]]))"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import numpy as np\n",
"from adjugate import adj\n",
"\n",
"M = np.random.rand(4, 4)\n",
"adjM = adj(M)\n",
"M, adjM"
]
},
{
"cell_type": "markdown",
"id": "f3564f39-5998-4805-aaba-f269e54930c7",
"metadata": {},
"source": [
"## Installation"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "1b2de14e-0fe8-4802-8d5f-e8c4804caa67",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Requirement already satisfied: adjugate in c:\\users\\sebas\\appdata\\local\\programs\\python\\python310\\lib\\site-packages (0.9.0)\n",
"Requirement already satisfied: numpy in c:\\users\\sebas\\appdata\\local\\programs\\python\\python310\\lib\\site-packages (from adjugate) (1.23.2)\n",
"Note: you may need to restart the kernel to use updated packages.\n"
]
}
],
"source": [
"pip install adjugate"
]
},
{
"cell_type": "markdown",
"id": "1f9c5ab4-3a86-41a0-b785-ab2e27c63f8f",
"metadata": {},
"source": [
"## Usage\n",
"\n",
"This package provides four functions:"
]
},
{
"cell_type": "markdown",
"id": "0bdebd1b-6410-4067-84ff-860b01b57214",
"metadata": {},
"source": [
"### submatrix\n",
"\n",
"`submatrix(M, i, j)`\n",
"\n",
"Removes the `i`-th row and `j`-th column of `M`. Multiple indices or slices can be provided."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "271159f2-d98e-4f5f-a8fa-b02eed514c10",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(array([[ 0, 1, 2, 3],\n",
" [ 4, 5, 6, 7],\n",
" [ 8, 9, 10, 11],\n",
" [12, 13, 14, 15]]),\n",
" array([[ 0, 1, 3],\n",
" [ 8, 9, 11],\n",
" [12, 13, 15]]))"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from adjugate import submatrix\n",
"\n",
"M = np.arange(16).reshape(4, 4)\n",
"M, submatrix(M, 1, 2)"
]
},
{
"cell_type": "markdown",
"id": "7c5868fc-ac90-4792-8b9e-038ae979b5e9",
"metadata": {},
"source": [
"### minor\n",
"\n",
"`minor(M, i, j)`\n",
"\n",
"Calculates the (`i`, `j`) minor of `M`."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "3257af04-e2d6-422b-80c3-980c0e4099bb",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"-0.2140487789380897"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from adjugate import minor\n",
"\n",
"M = np.random.rand(4, 4)\n",
"minor(M, 1, 2)"
]
},
{
"cell_type": "markdown",
"id": "ff038a2a-cf5b-4351-90cd-de7249e57dc4",
"metadata": {},
"source": [
"### adj\n",
"\n",
"`adj(M)`\n",
"\n",
"Calculates the adjugate of `M`."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "8d2262ca-f258-44bd-829e-022a7d974b70",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(array([[0.08665864, 0.99394655, 0.12535963, 0.26405097],\n",
" [0.5579125 , 0.86322768, 0.89414941, 0.568058 ],\n",
" [0.67013036, 0.84454395, 0.47131153, 0.19339756],\n",
" [0.66467323, 0.85295762, 0.13306573, 0.5569822 ]]),\n",
" array([[-0.23323852, -0.12057808, 0.24929258, 0.14698786],\n",
" [ 0.21400119, -0.06933021, 0.09234215, -0.06280701],\n",
" [-0.03500821, 0.21404878, 0.04025053, -0.21568468],\n",
" [-0.04102134, 0.19892593, -0.44852065, 0.29057721]]))"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"M, adj(M)"
]
},
{
"cell_type": "markdown",
"id": "0161d250-86c3-45c6-a24b-cd4eeb04e171",
"metadata": {},
"source": [
"### cof\n",
"\n",
"`cof(M)`\n",
"\n",
"Calculates the cofactor matrix of `M`."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "219e79e7-2d85-489d-909a-0c285c2d9a8a",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(array([[0.08665864, 0.99394655, 0.12535963, 0.26405097],\n",
" [0.5579125 , 0.86322768, 0.89414941, 0.568058 ],\n",
" [0.67013036, 0.84454395, 0.47131153, 0.19339756],\n",
" [0.66467323, 0.85295762, 0.13306573, 0.5569822 ]]),\n",
" array([[-0.23323852, 0.21400119, -0.03500821, -0.04102134],\n",
" [-0.12057808, -0.06933021, 0.21404878, 0.19892593],\n",
" [ 0.24929258, 0.09234215, 0.04025053, -0.44852065],\n",
" [ 0.14698786, -0.06280701, -0.21568468, 0.29057721]]))"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from adjugate import cof\n",
"\n",
"M, cof(M)"
]
},
{
"cell_type": "markdown",
"id": "bee2d755-596b-4aaf-a117-187bd55da16a",
"metadata": {},
"source": [
"## Speed\n",
"\n",
"If you know that you matrix is invertible, then `np.linalg.det(M) * np.linalg.inv(M)` might be a faster choice (O(3) instad of O(5)). But this is in general, especially as the determinant approaches zero, not possible or precise:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "ab860a15-1297-455b-b60e-43abe8b2c36e",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"N = 20\n",
"dets, errs = [], []\n",
"for _ in range(10000):\n",
" M = np.random.rand(N, N)\n",
" dets += [np.linalg.det(M)]\n",
" errs += [np.linalg.norm(adj(M)-np.linalg.det(M)*np.linalg.inv(M))]\n",
"\n",
"fig, ax = plt.subplots()\n",
"ax.scatter(dets, errs, marker='o', s=(72./fig.dpi)**2)\n",
"ax.set_yscale('log')\n",
"ax.set_xlim(-2, +2)\n",
"ax.set_ylim(1e-16, 1e-12)\n",
"ax.set_xlabel('det')\n",
"ax.set_ylabel('err')\n",
"plt.show()"
]
}
],
"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
}