{"id":22282755,"url":"https://github.com/warrenspe/pytrix","last_synced_at":"2026-04-30T18:31:22.852Z","repository":{"id":57458048,"uuid":"71513211","full_name":"warrenspe/pytrix","owner":"warrenspe","description":"Python matrix DAO implemented in C","archived":false,"fork":false,"pushed_at":"2016-12-04T05:45:19.000Z","size":213,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-25T04:41:38.628Z","etag":null,"topics":["matrix","matrix-functions","matrix-multiplication","point","python","python2","python3","rotation","strassen-winograd","vector"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/warrenspe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-10-20T23:44:44.000Z","updated_at":"2018-10-27T19:54:28.000Z","dependencies_parsed_at":"2022-09-07T04:10:18.821Z","dependency_job_id":null,"html_url":"https://github.com/warrenspe/pytrix","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/warrenspe/pytrix","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/warrenspe%2Fpytrix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/warrenspe%2Fpytrix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/warrenspe%2Fpytrix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/warrenspe%2Fpytrix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/warrenspe","download_url":"https://codeload.github.com/warrenspe/pytrix/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/warrenspe%2Fpytrix/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32473804,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"ssl_error","status_checked_at":"2026-04-30T13:12:06.837Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["matrix","matrix-functions","matrix-multiplication","point","python","python2","python3","rotation","strassen-winograd","vector"],"created_at":"2024-12-03T16:35:50.501Z","updated_at":"2026-04-30T18:31:22.837Z","avatar_url":"https://github.com/warrenspe.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pytrix\nPython utility which allows oeprations to be performed on Matrices, Vectors and Points.\n\n## Installation\npytrix can be installed using pip:\n\n`pip install pytrix`\n\nAlternatively, pytrix can be installed manually by cloning this repo and running the following command in the main directory:\n\n`python setup.py install`\n\n## Usage\nThe pytrix module contains 3 classes, Matrix, Vector, and Point.  These objects are immutable.  It also contains a few convenience functions for constructing certain special types of matrices.\n\n### Matrix\n\n#### Matrix.\\_\\_init__(...)\nMatrices can be instantiated by passing either a list containing the rows of the matrix, or by passing the rows of the matrix to the constructor itself.\n```\n\u003e\u003e\u003e print(pytrix.Matrix([[1, 2, 3], [4, 5, 6]]))\n[1.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n\u003e\u003e\u003e print(pytrix.Matrix([1, 2, 3], [4, 5, 6]))\n[1.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n```\n\n#### Matrix.\\_\\_getitem__(Int)\nMatrices can be indexed by their row to return a Vector.\n```\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6])\n\u003e\u003e\u003e m[1]\n\u003cpytrix.Vector object at 0x6ffffda0df0\u003e\n\u003e\u003e\u003e print(m[1])\n(4.0, 5.0, 6.0)\n```\n\n#### Matrix.\\_\\_add__(Matrix)\nMatrices can be added to other matrices having the same number of rows and columns.\n```\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6])\n\u003e\u003e\u003e print(m + m)\n[2.0, 4.0, 6.0]\n[8.0, 10.0, 12.0]\n\u003e\u003e\u003e print(m + pytrix.Matrix([1]))\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\nValueError: Matrices must be of the same dimensions.\n```\n\n#### Matrix.\\_\\_sub__(Matrix)\nMatrices can be subtracted from other matrices having the same number of rows and columns.\n```\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6])\n\u003e\u003e\u003e print(m - m)\n[0.0, 0.0, 0.0]\n[0.0, 0.0, 0.0]\n\u003e\u003e\u003e print(m - pytrix.Matrix([1]))\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\nValueError: Matrices must be of the same dimensions.\n```\n\n#### Matrix.\\_\\_mul__(MatrixOrVector)\nMatrices can be multiplied with other matrices and vectors to produce new matrices or vectors respectively.  If a large matrix is multiplied with another large matrix instead of using the Naive O(n^3) matrix multiplication, the application will use an implementation of the Strassen-Winograd matrix multiplication algorithm.  If this behaviour is either desired/undesired use of one algorithm or the other can be forced by using either the \\_strassenmul function, or \\_naiveMul function.  Note that Strassen-Winograd multiplication can only be applied to square matrices of the same size.\n```\n\u003e\u003e\u003e m1 = pytrix.Matrix([1, 2, 3], [4, 5, 6])\n\u003e\u003e\u003e m2 = pytrix.Matrix([1, 2], [3, 4], [5, 6])\n\u003e\u003e\u003e v1 = pytrix.Vector(5, 5, 5)\n\u003e\u003e\u003e print(v1)\n(5.0, 5.0, 5.0)\n\u003e\u003e\u003e print(m1)\n[1.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n\u003e\u003e\u003e print(m2)\n[1.0, 2.0]\n[3.0, 4.0]\n[5.0, 6.0]\n\n\u003e\u003e\u003e print(m1 * v1)\n(30.0, 75.0, 1.6e-322)\n\u003e\u003e\u003e print(m1 * m2)\n[22.0, 28.0]\n[49.0, 64.0]\n\u003e\u003e\u003e print(m1._naiveMul(m2))\n[22.0, 28.0]\n[49.0, 64.0]\n\u003e\u003e\u003e print(m1._strassenMul(m2, 2))\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\nValueError: Cannot perform Strassen-Winograd on non-square matrices.\n```\nFinally, the \\_strassenMul function requires a second parameter, which indicates the level recursion should halt at and naive matrix multiplication should be used to finish the computation.  This is because the Strassen-Winograd algorithm is a Divide-and-Conquor algorithm, and for matrices below a certain size it is faster to use the naive matrix multiplication algorithm.\n```\n\u003e\u003e\u003e m1 = pytrix.Matrix([9, 8], [7, 6])\n\u003e\u003e\u003e print(m1)\n[9.0, 8.0]\n[7.0, 6.0]\n\u003e\u003e\u003e m2 = pytrix.Matrix([5, 4], [3, 2])\n\u003e\u003e\u003e print(m2)\n[5.0, 4.0]\n[3.0, 2.0]\n\u003e\u003e\u003e print(m1._strassenMul(m2, 2))\n[69.0, 52.0]\n[53.0, 40.0]\n```\n\n#### Matrix.__neg__()\nMatrices can be component-wise negated.\n```\n\u003e\u003e\u003e m1 = pytrix.Matrix([1, 2, 3], [4, 5, 6])\n\u003e\u003e\u003e print(m)\n[1.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n\u003e\u003e\u003e print(-m1)\n[-1.0, -2.0, -3.0]\n[-4.0, -5.0, -6.0]\n```\n\n#### Matrix.__bool__()\nMatrices are considered True unless all its components are 0.\n```\n\u003e\u003e\u003e print(bool(pytrix.Matrix([0, 0, 1])))\nTrue\n\u003e\u003e\u003e print(bool(pytrix.Matrix([0, 0, 0])))\nFalse\n```\n\n#### Matrix.copy()\nReturns a new copy of this Matrix.\n```\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6], [7, 8, 9])\n\u003e\u003e\u003e print(id(m))\n7696580423856\n\u003e\u003e\u003e print(id(m.copy()))\n7696580424016\n```\n\n#### Matrix.row(Int)\nMatrix.row returns the ith row of the Matrix as a Vector.\n```\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6])\n\u003e\u003e\u003e m.row(1)\n\u003cpytrix.Vector object at 0x6fffff8af50\u003e\n\u003e\u003e\u003e print(m.row(1))\n(4.0, 5.0, 6.0)\n```\n\n#### Matrix.column(Int)\nMatrix.column returns the ith column of the Matrix as a Vector.\n```\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6])\n\u003e\u003e\u003e m.column(1)\n\u003cpytrix.Vector object at 0x6ffffda0f30\u003e\n\u003e\u003e\u003e print(m.column(1))\n(2.0, 5.0)\n```\n\n#### Matrix.transpose()\nMatrix.transpose creates a new matrix from the transpose of the matrix it is called on.\n```\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6])\n\u003e\u003e\u003e print(m)\n[1.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n\u003e\u003e\u003e print(m.transpose())\n[1.0, 4.0]\n[2.0, 5.0]\n[3.0, 6.0]\n```\n\n#### Matrix.permute(row1, row2)\nMatrix.permute creates a new Matrix identical to the one having the function run on it, with its ith and jth rows swapped.\n```\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6])\n\u003e\u003e\u003e print(m)\n[1.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n\u003e\u003e\u003e print(m.permute(0, 1))\n[4.0, 5.0, 6.0]\n[1.0, 2.0, 3.0]\n```\n\n#### Matrix.isSymmetrical()\nDetermines whether or not this matrix is symmetrical or not.\n```\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6])\n\u003e\u003e\u003e print(m)\n[1.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n\u003e\u003e\u003e print(m.isSymmetrical())\nFalse\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6], [7, 8, 9])\n\u003e\u003e\u003e print(m)\n[1.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n[7.0, 8.0, 9.0]\n\u003e\u003e\u003e print(m.isSymmetrical())\nFalse\n\u003e\u003e\u003e m = pytrix.Matrix([1, 0, 1], [0, 1, 0], [1, 0, 1])\n\u003e\u003e\u003e print(m)\n[1.0, 0.0, 1.0]\n[0.0, 1.0, 0.0]\n[1.0, 0.0, 1.0]\n\u003e\u003e\u003e print(m.isSymmetrical())\nTrue\n```\n\n#### Matrix.isIdentity()\nDetermines whether or not this matrix is an identity matrix.\n```\n\u003e\u003e\u003e pytrix.identityMatrix(50).isIdentity()\nTrue\n\u003e\u003e\u003e pytrix.permutationMatrix(50, 0, 1).isIdentity()\nFalse\n```\n\n#### Matrix.isInvertible()\nDetermines whether or not this matrix is invertible.  Note that this function has nearly the same cost as actually creating the inverse, so if an inverse will be taken at some point it would be wiser to actually try to construct the inverse instead of using this function.\n```\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6], [7, 8, 9])\n\u003e\u003e\u003e m.isInvertible()\nFalse\n\u003e\u003e\u003e m.inverse()\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\nValueError: Cannot take inverse of non-invertible matrix.\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6], [7, 8, 10])\n\u003e\u003e\u003e m.isInvertible()\nTrue\n\u003e\u003e\u003e m.inverse()\n\u003cpytrix.Matrix object at 0x6ffffda0d30\u003e\n```\n\n#### Matrix.inverse()\nConstructs the inverse of the Matrix if possible, else raises a ValueError.\n```\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6], [7, 8, 9])\n\u003e\u003e\u003e m.inverse()\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\nValueError: Cannot take inverse of non-invertible matrix.\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6], [7, 8, 10])\n\u003e\u003e\u003e m.isInvertible()\nTrue\n\u003e\u003e\u003e print(m.inverse())\n[-0.6666666666666665, -1.3333333333333335, 1.0]\n[-0.6666666666666667, 3.6666666666666665, -2.0]\n[1.0, -2.0, 1.0]\n\u003e\u003e\u003e print(m.inverse() * m)\n[1.0, 0.0, 0.0]\n[0.0, 1.0, 0.0]\n[0.0, 0.0, 1.0]\n```\n\n#### Matrix.rank()\nDetermines the rank of the matrix's reduced row echelon form.\n```\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6], [7, 8, 10])\n\u003e\u003e\u003e print(m.rank())\n3\n\u003e\u003e\u003e m = pytrix.Matrix([1, 0, 0], [0, 1, 0], [0, 0, 0])\n\u003e\u003e\u003e print(m.rank())\n2\n```\n\n#### Matrix.trace()\nDetermines the trace of the matrix.  Note that this is only a valid operation for square matrices.\n```\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6], [7, 8, 9])\n\u003e\u003e\u003e print(m)\n[1.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n[7.0, 8.0, 9.0]\n\u003e\u003e\u003e print(m.trace())\n15.0\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6])\n\u003e\u003e\u003e m.trace()\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\nValueError: Matrix.trace can only computed on square matrices.\n```\n\n#### Matrix.determinant()\nDetermines the determinant of the matrix.\n```\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6], [7, 8, 9])\n\u003e\u003e\u003e print(m)\n[1.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n[7.0, 8.0, 9.0]\n\u003e\u003e\u003e print(m.determinant())\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6], [7, 8, 10])\n\u003e\u003e\u003e print(m)\n[1.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n[7.0, 8.0, 10.0]\n\u003e\u003e\u003e print(m.determinant())\n-3.0\n```\n\n#### Matrix.gaussianElim()\nCreates a new matrix from this matrix, by performing gaussian elimination on the matrix, to convert it into a reduced row echelon form.\n```\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6], [7, 8, 10])\n\u003e\u003e\u003e print(m.gaussianElim())\n[1.0, 2.0, 3.0]\n[0.0, -3.0, -6.0]\n[0.0, 0.0, 1.0]\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6])\n\u003e\u003e\u003e print(m.gaussianElim())\n[1.0, 2.0, 3.0]\n[0.0, -3.0, -6.0]\n```\n\n#### Matrix.factorLU()\nFactors a matrix into two new matrices L and U, having M = L * U, where L is lower triangular, and U is upper triangular.  Note that m must be invertible.\n```\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6], [7, 8, 10])\n\u003e\u003e\u003e print(m)\n[1.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n[7.0, 8.0, 10.0]\n\u003e\u003e\u003e l, u = m.factorLU()\n\u003e\u003e\u003e print(l)\n[1.0, 0.0, 0.0]\n[4.0, 1.0, 0.0]\n[7.0, 2.0, 1.0]\n\u003e\u003e\u003e print(u)\n[1.0, 2.0, 3.0]\n[0.0, -3.0, -6.0]\n[0.0, 0.0, 1.0]\n\u003e\u003e\u003e print(l * u)\n[1.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n[7.0, 8.0, 10.0]\n\u003e\u003e\u003e m = pytrix.Matrix([0, 0, 1], [0, 1, 0], [1, 0, 0])\n\u003e\u003e\u003e print(m)\n[0.0, 0.0, 1.0]\n[0.0, 1.0, 0.0]\n[1.0, 0.0, 0.0]\n\u003e\u003e\u003e m.factorLU()\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\nValueError: Cannot factor non-invertible Matrix.\n```\n\n#### Matrix.factorLDU()\nFactors a matrix into three new matrices, L, D, and U, having M = L * D * U, where L is lower triangular, D is diagonal, and U is upper triangular.  Note that m must be invertible.\n```\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6], [7, 8, 10])\n\u003e\u003e\u003e print(m)\n[1.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n[7.0, 8.0, 10.0]\n\u003e\u003e\u003e l, d, u = m.factorLDU()\n\u003e\u003e\u003e print(l)\n[1.0, 0.0, 0.0]\n[4.0, 1.0, 0.0]\n[7.0, 2.0, 1.0]\n\u003e\u003e\u003e print(d)\n[1.0, 0.0, 0.0]\n[0.0, -3.0, 0.0]\n[0.0, 0.0, 1.0]\n\u003e\u003e\u003e print(u)\n[1.0, 2.0, 3.0]\n[0.0, 1.0, 2.0]\n[0.0, 0.0, 1.0]\n\u003e\u003e\u003e print(l * d * u)\n[1.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n[7.0, 8.0, 10.0]\n\u003e\u003e\u003e m = pytrix.Matrix([0, 0, 1], [0, 1, 0], [1, 0, 0])\n\u003e\u003e\u003e print(m)\n[0.0, 0.0, 1.0]\n[0.0, 1.0, 0.0]\n[1.0, 0.0, 0.0]\n\u003e\u003e\u003e m.factorLDU()\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\nValueError: Cannot factor non-invertible Matrix.\n```\n\n#### Matrix.factorPLU()\nFactors a matrix into three new matrices, P, L, and U, having P * M = L * U, where P is a permutation matrix, L is lower triangular, and U is upper triangular.  Note that m need not be invertible.\n```\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6], [7, 8, 9])\n\u003e\u003e\u003e print(m)\n[1.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n[7.0, 8.0, 9.0]\n\u003e\u003e\u003e p, l, u = m.factorPLU()\n\u003e\u003e\u003e print(p)\n[1.0, 0.0, 0.0]\n[0.0, 1.0, 0.0]\n[0.0, 0.0, 1.0]\n\u003e\u003e\u003e print(l)\n[1.0, 0.0, 0.0]\n[4.0, 1.0, 0.0]\n[7.0, 2.0, 1.0]\n\u003e\u003e\u003e print(u)\n[1.0, 2.0, 3.0]\n[0.0, -3.0, -6.0]\n[0.0, 0.0, 0.0]\n\u003e\u003e\u003e print(p * m)\n[1.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n[7.0, 8.0, 9.0]\n\u003e\u003e\u003e print (l * u)\n[1.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n[7.0, 8.0, 9.0]\n```\n\n#### Matrix.factorPLDU()\nFactors a matrix into four new matrices, P, L, D, and U, having P * M = L * D * U, where P is a permutation matrix, L is lower triangular, D is diagonal, and U is upper triangular.  Note that m need not be invertible.\n```\n\u003e\u003e\u003e m = pytrix.Matrix([0, 2, 3], [4, 5, 6], [7, 8, 9])\n\u003e\u003e\u003e print(m)\n[0.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n[7.0, 8.0, 9.0]\n\u003e\u003e\u003e p, l, d, u = m.factorPLDU()\n\u003e\u003e\u003e print(p)\n[0.0, 1.0, 0.0]\n[1.0, 0.0, 0.0]\n[0.0, 0.0, 1.0]\n\u003e\u003e\u003e print(l)\n[1.0, 0.0, 0.0]\n[0.0, 1.0, 0.0]\n[1.75, -0.375, 1.0]\n\u003e\u003e\u003e print(d)\n[4.0, 0.0, 0.0]\n[0.0, 2.0, 0.0]\n[0.0, 0.0, -0.375]\n\u003e\u003e\u003e print(u)\n[1.0, 1.25, 1.5]\n[0.0, 1.0, 1.5]\n[0.0, 0.0, 1.0]\n\u003e\u003e\u003e print(p * m)\n[4.0, 5.0, 6.0]\n[0.0, 2.0, 3.0]\n[7.0, 8.0, 9.0]\n\u003e\u003e\u003e print(l * d * u)\n[4.0, 5.0, 6.0]\n[0.0, 2.0, 3.0]\n[7.0, 8.0, 9.0]\n```\n\n#### Matrix Attributes\nMatrices have two attributes, `rows` and `columns` which are integer values corresponding to the matrices' number of rows and columns\n```\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6])\n\u003e\u003e\u003e print(m.rows)\n2\n\u003e\u003e\u003e print(m.columns)\n3\n```\n\n### Vector\n\n#### Vector.\\_\\_init__(...)\nVectors can be instantiated by passing either a list containing the values of the vector, or by passing the values of the vector to the constructor itself.\n```\n\u003e\u003e\u003e v = pytrix.Vector([1, 2, 3])\n\u003e\u003e\u003e print(v)\n(1.0, 2.0, 3.0)\n\u003e\u003e\u003e v = pytrix.Vector(1, 2, 3)\n\u003e\u003e\u003e print(v)\n(1.0, 2.0, 3.0)\n```\n\n#### Vector.\\_\\_getitem__(Int)\nIt is possible to extract the components from a Vector using dictionary-style indexing.\n```\n\u003e\u003e\u003e v = pytrix.Vector(1, 2, 3)\n\u003e\u003e\u003e print(v[0])\n1.0\n\u003e\u003e\u003e print(v[1])\n2.0\n\u003e\u003e\u003e print(v[2])\n3.0\n\u003e\u003e\u003e print(v[3])\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\nIndexError: Cannot return item in index 3 of Vector with 3 dimensions.\n```\n\n#### Vector.\\_\\_add__(Vector)\nA vector can be component-wise added with another vector to produce a new third vector.\n```\n\u003e\u003e\u003e v1 = pytrix.Vector(1, 2, 3)\n\u003e\u003e\u003e v2 = pytrix.Vector(4, 5, 6)\n\u003e\u003e\u003e print(v1 + v2)\n(5.0, 7.0, 9.0)\n\u003e\u003e\u003e v2 = pytrix.Vector(4, 5)\n\u003e\u003e\u003e print(v1 + v2)\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\nValueError: Vectors must be of the same dimensions.\n```\n\n#### Vector.\\_\\_sub__(Vector)\nA vector can be component-wise subtracted from another veector to produce a new third vector.\n```\n\u003e\u003e\u003e v1 = pytrix.Vector(1, 2, 3)\n\u003e\u003e\u003e v2 = pytrix.Vector(4, 5, 6)\n\u003e\u003e\u003e print(v1 - v2)\n(-3.0, -3.0, -3.0)\n\u003e\u003e\u003e v2 = pytrix.Vector(4, 5)\n\u003e\u003e\u003e print(v1 - v2)\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\nValueError: Vectors must be of the same dimensions.\n```\n\n#### Vector.\\_\\_mul__(MatrixOrScalar)\nA vector can be multiplied by either a matrix, or a scalar to produce a new vector. Note that if it is being multiplied by a matrix it will always take the form M\\*V.  In other words, the matrix will always be the left operand and the vector the right.\n```\n\u003e\u003e\u003e v = pytrix.Vector(1, 2, 3)\n\u003e\u003e\u003e m = pytrix.Matrix([1, 2, 3], [4, 5, 6])\n\u003e\u003e\u003e print(v)\n(1.0, 2.0, 3.0)\n\u003e\u003e\u003e print(m)\n[1.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n\u003e\u003e\u003e print(v * m)\n(14.0, 32.0)\n\u003e\u003e\u003e print(v * 5)\n(5.0, 10.0, 15.0)\n```\n\n#### Vector.\\_\\_div__(Scalar)\nCreates a new vector by dividing the components of a vector by a scalar.\n```\n\u003e\u003e\u003e v = pytrix.Vector(1, 2, 3)\n\u003e\u003e\u003e print(v)\n(1.0, 2.0, 3.0)\n\u003e\u003e\u003e print(v / 5)\n(0.2, 0.4, 0.6)\n```\n\n#### Vector.\\_\\_neg__()\nCreates a new vector by negating the components of a vector.\n```\n\u003e\u003e\u003e v = pytrix.Vector(1, 2, 3)\n\u003e\u003e\u003e print(v)\n(1.0, 2.0, 3.0)\n\u003e\u003e\u003e print(-v)\n(-1.0, -2.0, -3.0)\n```\n\n#### Vector.\\_\\_bool__()\nReturns True if the vector contains any non-zero components, else False.\n```\n\u003e\u003e\u003e v = pytrix.Vector(0, 0, 0)\n\u003e\u003e\u003e print(bool(v))\nFalse\n```\n\n#### Vector.copy()\nReturns a new copy of this Vector.\n```\n\u003e\u003e\u003e v = pytrix.Vector(1, 2, 3)\n\u003e\u003e\u003e print(id(v))\n7696578907216\n\u003e\u003e\u003e print(id(v.copy()))\n7696578907696\n\u003e\u003e\u003e\n```\n\n#### Vector.dot(Vector)\nCalculates the dot product of this vector with another.\n```\n\u003e\u003e\u003e v = pytrix.Vector(1, 2, 3)\n\u003e\u003e\u003e v.dot(v)\n14.0\n```\n\n#### Vector.cross(Vector)\nCalculates the cross product of this vector with another.\n```\n\u003e\u003e\u003e v1 = pytrix.Vector(1, 2, 3)\n\u003e\u003e\u003e v2 = pytrix.Vector(4, 5, 6)\n\u003e\u003e\u003e print(v1.cross(v2))\n(-3.0, 6.0, -3.0)\n```\n\n#### Vector.length()\nCalculates the length of this vector.\n```\n\u003e\u003e\u003e v = pytrix.Vector(1, 2, 3)\n\u003e\u003e\u003e print(v.length())\n3.7416573867739413\n\u003e\u003e\u003e v = pytrix.Vector(0, 0, 0)\n\u003e\u003e\u003e print(v.length())\n0.0\n```\n\n#### Vector.unit()\nReturns a new vector with the same direction as this vector but with a length of 1\n```\n\u003e\u003e\u003e v = pytrix.Vector(1, 2, 3)\n\u003e\u003e\u003e u = v.unit()\n\u003e\u003e\u003e print(u)\n(0.2672612419124244, 0.5345224838248488, 0.8017837257372732)\n\u003e\u003e\u003e print(u.length())\n1.0\n```\n\n#### Vector.isUnit()\nDetermines whether or not the vector is a unit vector (ie has length 1)\n```\n\u003e\u003e\u003e v = pytrix.Vector(1, 2, 3)\n\u003e\u003e\u003e print(v.isUnit())\nFalse\n\u003e\u003e\u003e v = pytrix.Vector(1, 0, 0)\n\u003e\u003e\u003e print(v.isUnit())\nTrue\n```\n\n#### Vector.angleBetween(Vector)\nCalculates the angle between two vectors in radians.\n```\n\u003e\u003e\u003e v1 = pytrix.Vector(1, 0, 0)\n\u003e\u003e\u003e v1.angleBetween(v1)\n0.0\n\u003e\u003e\u003e v2 = pytrix.Vector(0, 1, 0)\n\u003e\u003e\u003e v1.angleBetween(v2)\n1.5707963267948966\n```\n\n#### Vector.isOrthogonal(Vector)\nDetermines whether two vectors are orthogonal to each other.\n```\n\u003e\u003e\u003e v1 = pytrix.Vector(1, 0, 0)\n\u003e\u003e\u003e v1.isOrthogonal(v1)\nFalse\n\u003e\u003e\u003e v2 = pytrix.Vector(0, 1, 0)\n\u003e\u003e\u003e v1.isOrthogonal(v2)\nTrue\n```\n\n#### Vector Attributes\nVectors have a single attribute, `dimensions` which is an integer value corresponding to the vectors' number of components.\n```\n\u003e\u003e\u003e v = pytrix.Vector(1, 2, 3, 4)\n\u003e\u003e\u003e print(v.dimensions)\n4\n```\n\n### Point\n\n#### Point.\\_\\_init__(...)\nPoints can be instantiated by passing either a list containing the coordinates of the point, or by passing the coordinates of the point to the constructor itself.\n```\n\u003e\u003e\u003e p = pytrix.Point([1, 2, 3])\n\u003e\u003e\u003e print(p)\n(1.0, 2.0, 3.0)\n\u003e\u003e\u003e p = pytrix.Point(1, 2, 3)\n\u003e\u003e\u003e print(p)\n(1.0, 2.0, 3.0)\n```\n\n#### Point.\\_\\_getitem__(Int)\nIt is possible to extract the coordinates from a Point using dictionary-style indexing.\n```\n\u003e\u003e\u003e p = pytrix.Point(1, 2, 3)\n\u003e\u003e\u003e print(p[0])\n1.0\n\u003e\u003e\u003e print(p[1])\n2.0\n\u003e\u003e\u003e print(p[2])\n3.0\n\u003e\u003e\u003e print(p[3])\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\nIndexError: Cannot return item in index 3 of Point with 3 dimensions.\n```\n\n#### Point.\\_\\_add__(Vector)\nA point can be added with a vector to construct a new point object.\n```\n\u003e\u003e\u003e p = pytrix.Point(1, 2, 3)\n\u003e\u003e\u003e v = pytrix.Vector(1, 2, 3)\n\u003e\u003e\u003e print(p + v)\n(2.0, 4.0, 6.0)\n```\n\n#### Point.\\_\\_sub__(PointOrVector)\nA point can be subtracted from either a vector or another point.  If it is subtracted from a vector, it returns a Point, similar to how Point.\\_\\_add__ works.  If it is subtracted from another point, it returns a vector, which maps from the second point to the first.\n```\n\u003e\u003e\u003e p1 = pytrix.Point(2, 3, 4)\n\u003e\u003e\u003e p2 = pytrix.Point(1, 2, 3)\n\u003e\u003e\u003e p1 - p2\n\u003cpytrix.Vector object at 0x6ffffda0cd0\u003e\n\u003e\u003e\u003e v = p1 - p2\n\u003e\u003e\u003e print(v)\n(1.0, 1.0, 1.0)\n\u003e\u003e\u003e p1 - v\n\u003cpytrix.Point object at 0x6ffffda0e30\u003e\n\u003e\u003e\u003e print(p1 - v)\n(1.0, 2.0, 3.0)\n```\n\n#### Point.\\_\\_neg__()\nConstructs a new point by negating the coordinates of this point.\n```\n\u003e\u003e\u003e p = pytrix.Point(1, 2, 3)\n\u003e\u003e\u003e print(p)\n(1.0, 2.0, 3.0)\n\u003e\u003e\u003e print(-p)\n(-1.0, -2.0, -3.0)\n```\n\n#### Point.\\_\\_bool__()\nReturns True if the point is not on the 0-coordinate, else False.\n```\n\u003e\u003e\u003e p = pytrix.Point(1, 2, 3)\n\u003e\u003e\u003e print(bool(p))\nTrue\n\u003e\u003e\u003e p = pytrix.Point(0, 0, 0)\n\u003e\u003e\u003e print(bool(p))\nFalse\n```\n\n#### Point.copy()\nReturns a new copy of this point.\n```\n\u003e\u003e\u003e p = pytrix.Point(1, 2, 3)\n\u003e\u003e\u003e print(id(p))\n7696578907664\n\u003e\u003e\u003e print(id(p.copy()))\n7696580915024\n```\n\n### Convenience Matrix Functions\n\n#### identityMatrix(dimensions)\nConstructs an identity matrix of a specified number of dimensions\n```\n\u003e\u003e\u003e print(pytrix.identityMatrix(1))\n[1.0]\n\u003e\u003e\u003e print(pytrix.identityMatrix(2))\n[1.0, 0.0]\n[0.0, 1.0]\n\u003e\u003e\u003e print(pytrix.identityMatrix(3))\n[1.0, 0.0, 0.0]\n[0.0, 1.0, 0.0]\n[0.0, 0.0, 1.0]\n```\n\n#### permutationMatrix(dimensions, row1, row2)\nConstructs a permutation matrix of the specified number of dimensions which swaps the two given rows of a matrix it's multiplied with.\n```\n\u003e\u003e\u003e a = pytrix.Matrix([1, 2, 3], [4, 5, 6], [7, 8, 9])\n\u003e\u003e\u003e print(a)\n[1.0, 2.0, 3.0]\n[4.0, 5.0, 6.0]\n[7.0, 8.0, 9.0]\n\u003e\u003e\u003e p = pytrix.permutationMatrix(3, 0, 1)\n\u003e\u003e\u003e print(p)\n[0.0, 1.0, 0.0]\n[1.0, 0.0, 0.0]\n[0.0, 0.0, 1.0]\n\u003e\u003e\u003e print(p * a)\n[4.0, 5.0, 6.0]\n[1.0, 2.0, 3.0]\n[7.0, 8.0, 9.0]\n```\n\n#### rotation2DMatrix(radians)\nConstructs a 2 dimensional rotation matrix which can be applied to a vector to rotate it by the specified number of radians.\n```\n\u003e\u003e\u003e v = pytrix.Vector(1, 1)\n\u003e\u003e\u003e print(v)\n(1.0, 1.0)\n\u003e\u003e\u003e r = pytrix.rotation2DMatrix(math.pi)\n\u003e\u003e\u003e print(r)\n[-1.0, -1.2246467991473532e-16]\n[1.2246467991473532e-16, -1.0]\n\u003e\u003e\u003e print(r * v)\n(-1.0000000000000002, -0.9999999999999999)\n```\n\n#### rotation3DMatrix(radians)\nFunctions the same was as rotation2DMatrix, except creates a rotation matrix which can be applied to vectors with 3 dimensions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwarrenspe%2Fpytrix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwarrenspe%2Fpytrix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwarrenspe%2Fpytrix/lists"}