% Sage Linear Algebra Quick Reference
% (c) 2009 by Robert A. Beezer
% Licensed with the GNU Free Documentation License (GFDL)
%   http://www.gnu.org/copyleft/fdl.html
%
%  History
%
%    2009-05-10  Initial version based on Sage 3.4
%    2009-05-13  Added right paren to vector u in "vector operations" section
%    2010-08-15  Miscellaneous edits
%    2011-12-12  Update to Sage 4.8
%
%
\documentclass{article}
\usepackage{graphicx}  
\usepackage[landscape]{geometry}
\usepackage[pdftex]{color}
\usepackage{url}
\usepackage{multicol}
\usepackage{amsmath}
\usepackage{amsfonts}
\newcommand{\ex}{\color{blue}}
\newcommand{\warn}{\bf\color{red}}
\pagestyle{empty}
\advance\topmargin-.9in
\advance\textheight2in
\advance\textwidth3.0in
\advance\oddsidemargin-1.45in
\advance\evensidemargin-1.45in
\parindent0pt
\parskip2pt
% Section break, dictates column widths?
\newcommand{\hr}{\centerline{\rule{3.5in}{1pt}}}
% Adjust gap to affect spacing, page count
\newcommand{\sect}[1]{\hr\par\vspace*{2pt}\textbf{#1}\par}
% Mandatory indentation on subsidiary lines
\newcommand{\skipin}{\hspace*{12pt}}
\begin{document}
\begin{multicols*}{3}
\begin{center}
\textbf{Sage Quick Reference: Linear Algebra}\\
Robert A. Beezer\\
Sage Version 4.8\\
\url{http://wiki.sagemath.org/quickref}\\
GNU Free Document License, extend for your own use\\
Based on work by Peter Jipsen, William Stein 
\end{center}
% backup over center environment gap
\vspace{-2ex}
%*********************************************
\sect{Vector Constructions}
{\warn Caution}: First entry of a vector is numbered 0\\
{\ex\verb!u = vector(QQ, [1, 3/2, -1])!} length 3 over rationals\\
{\ex\verb!v = vector(QQ, {2:4, 95:4, 210:0})!}\\
\skipin 211 entries, nonzero in entry 4 and entry 95, sparse
\par
%*********************************************
\sect{Vector Operations}
{\ex\verb!u = vector(QQ, [1, 3/2, -1])!}\\
{\ex\verb!v = vector(ZZ, [1, 8, -2])!}\\
{\ex\verb!2*u - 3*v!} linear combination\\
{\ex\verb!u.dot_product(v)!}\\
{\ex\verb!u.cross_product(v)!}  order: \verb!u!$\times$\verb!v!\\
{\ex\verb!u.inner_product(v)!}  inner product matrix from parent\\
{\ex\verb!u.pairwise_product(v)!} vector as a result\\
{\ex\verb!u.norm() == u.norm(2)!} Euclidean norm\\
{\ex\verb!u.norm(1)!} sum of entries\\
{\ex\verb!u.norm(Infinity)!} maximum entry\\
{\ex\verb!A.gram_schmidt()!} converts the rows of matrix \verb!A!
\par
%*********************************************
\sect{Matrix Constructions}
{\warn Caution}: Row, column numbering begins at 0\\
{\ex\verb!A = matrix(ZZ, [[1,2],[3,4],[5,6]])!}\\
\skipin $3\times 2$ over the integers\\
{\ex\verb!B = matrix(QQ, 2, [1,2,3,4,5,6])!}\\
\skipin 2 rows from a list, so $2\times 3$ over rationals\\
{\ex\verb!C = matrix(CDF, 2, 2, [[5*I, 4*I], [I, 6]])!}\\
\skipin complex entries, 53-bit precision\\
{\ex\verb!Z = matrix(QQ, 2, 2, 0)!} zero matrix\\
{\ex\verb!D = matrix(QQ, 2, 2, 8)!}\\
\skipin diagonal entries all $8$, other entries zero\\
{\ex\verb!E = block_matrix([[P,0],[1,R]])!}, very flexible input\\
{\ex\verb!II = identity_matrix(5)!} $5\times5$ identity matrix\\
\skipin\verb!I! = $\sqrt{-1}$, do not overwrite with matrix name\\
{\ex\verb!J = jordan_block(-2,3)!}\\
\skipin $3\times 3$ matrix, $-2$ on diagonal, $1$'s on super-diagonal
{\ex\verb!var('x y z'); K = matrix(SR, [[x,y+z],[0,x^2*z]])!}\\
\skipin symbolic expressions live in the ring \verb!SR!\\
{\ex\verb!L = matrix(ZZ, 20, 80, {(5,9):30, (15,77):-6})!}\\
\skipin $20\times 80$, two non-zero entries, sparse representation
\par
%*********************************************
\sect{Matrix Multiplication}
{\ex\verb!u = vector(QQ, [1,2,3])!},\quad{\ex\verb!v = vector(QQ, [1,2])!}\\
{\ex\verb!A = matrix(QQ, [[1,2,3],[4,5,6]])!}\\
{\ex\verb!B = matrix(QQ, [[1,2],[3,4]])!}\\
{\ex\verb!u*A!},\quad
{\ex\verb!A*v!},\quad
{\ex\verb!B*A!},\quad
{\ex\verb!B^6!},\quad
{\ex\verb!B^(-3)!} all possible\\
{\ex\verb!B.iterates(v, 6)!}  produces $vB^0, vB^1,\dots, vB^5$\\
\skipin\verb!rows = False! moves \verb!v! to the right of matrix powers\\
{\ex\verb!f(x)=x^2+5*x+3!} then {\ex\verb!f(B)!} is possible\\
{\ex\verb!B.exp()!} matrix exponential, i.e.\ $\sum_{k=0}^{\infty}\frac{1}{k!}B^k$
\par
%*********************************************
\sect{Matrix Spaces}
{\ex\verb!M = MatrixSpace(QQ, 3, 4)!} is space of $3\times 4$ matrices\\
{\ex\verb!A = M([1,2,3,4,5,6,7,8,9,10,11,12])!}\\
\skipin coerce list to element of \verb!M!,  a $3\times 4$ matrix over \verb!QQ!\\
{\ex\verb!M.basis()!}\\
{\ex\verb!M.dimension()!}\\
{\ex\verb!M.zero_matrix()!}
\par
%*********************************************
\sect{Matrix Operations}
{\ex\verb!5*A+2*B!} linear combination\\
{\ex\verb!A.inverse()!}, {\ex\verb!A^(-1)!}, {\ex\verb!~A!}, singular is \verb!ZeroDivisionError!\\
{\ex\verb!A.transpose()!}\\
{\ex\verb!A.conjugate()!} entry-by-entry complex conjugates\\
{\ex\verb!A.conjugate_transpose()!}\\
{\ex\verb!A.antitranspose()!} transpose + reverse orderings\\
{\ex\verb!A.adjoint()!}  matrix of cofactors\\
{\ex\verb!A.restrict(V)!} restriction to invariant subspace \verb!V!
\par
%*********************************************
\sect{Row Operations}
Row Operations: (change matrix in place)\\
{\warn Caution}: first row is numbered 0\\
{\ex\verb!A.rescale_row(i,a)!} \verb!a*!(row \verb!i!)\\
{\ex\verb!A.add_multiple_of_row(i,j,a)!} \verb!a*!(row \verb!j!) + row \verb!i!\\
{\ex\verb!A.swap_rows(i,j)!}\\
Each has a column variant, \verb!row!$\rightarrow$\verb!col!\\
For a new matrix, use e.g.\ {\ex\verb!B = A.with_rescaled_row(i,a)!}
\par
%*********************************************
\sect{Echelon Form}
{\ex\verb!A.rref()!},
{\ex\verb!A.echelon_form()!},
{\ex\verb!A.echelonize()!}\\
{\warn Note}: \verb!rref()! promotes matrix to fraction field\\
{\ex\verb!A = matrix(ZZ,[[4,2,1],[6,3,2]])!}\\
\begin{tabular}{ll}
{\ex\verb!A.rref()!} & {\ex\verb!A.echelon_form()!}\\
$\left(\begin{array}{rrr}
2 & 1 & 0 \\
0 & 0 & 1
\end{array}\right)$
&
$\left(\begin{array}{rrr}
1 & \frac{1}{2} & 0 \\
0 & 0 & 1
\end{array}\right)$
\end{tabular}\\
{\ex\verb!A.pivots()!} indices of columns spanning column space\\
{\ex\verb!A.pivot_rows()!} indices of rows spanning row space
\par
%*********************************************
\sect{Pieces of Matrices}
{\warn Caution}: row, column numbering begins at 0\\
{\ex\verb!A.nrows()!}, {\ex\verb!A.ncols()!}\\
{\ex\verb!A[i,j]!} entry in row \verb!i! and column \verb!j!\\
{\ex\verb!A[i]!} row \verb!i! as immutable Python tuple.  Thus,\\
\skipin{\warn Caution}: OK: \verb!A[2,3] = 8!, Error: \verb!A[2][3] = 8!\\
{\ex\verb!A.row(i)!} returns row \verb!i! as Sage vector\\
{\ex\verb!A.column(j)!} returns column \verb!j! as Sage vector\\
{\ex\verb!A.list()!} returns single Python list, row-major order\\
{\ex\verb!A.matrix_from_columns([8,2,8])!}\\
\skipin new matrix from columns in list, repeats OK\\
{\ex\verb!A.matrix_from_rows([2,5,1])!}\\
\skipin new matrix from rows in list, out-of-order OK\\
{\ex\verb!A.matrix_from_rows_and_columns([2,4,2],[3,1])!}\\
\skipin common to the rows and the columns\\
{\ex\verb!A.rows()!}  all rows as a list of tuples\\
{\ex\verb!A.columns()!}  all columns as a list of tuples\\
{\ex\verb!A.submatrix(i,j,nr,nc)!}\\
\skipin start at entry \verb!(i,j)!, use \verb!nr! rows, \verb!nc! cols\\
{\ex\verb!A[2:4,1:7]!}, {\ex\verb!A[0:8:2,3::-1]!} Python-style list slicing 
\par
%*********************************************
\sect{Combining Matrices}
{\ex\verb!A.augment(B)!}  \verb!A! in first columns, matrix \verb!B! to the right\\
{\ex\verb!A.stack(B)!}  \verb!A! in top rows, \verb!B! below; \verb!B! can be a vector\\
{\ex\verb!A.block_sum(B)!}  Diagonal, \verb!A! upper left, \verb!B! lower right\\
{\ex\verb!A.tensor_product(B)!}  Multiples of \verb!B!, arranged as in \verb!A!
\par
%*********************************************
\sect{Scalar Functions on Matrices}
{\ex\verb!A.rank()!},\quad{\ex\verb!A.right_nullity()!}\\
{\ex\verb!A.left_nullity() == A.nullity()!}\\
{\ex\verb!A.determinant() == A.det()!}\\
{\ex\verb!A.permanent()!},\quad{\ex\verb!A.trace()!}\\
{\ex\verb!A.norm() == A.norm(2)!} Euclidean norm\\
{\ex\verb!A.norm(1)!} largest column sum\\
{\ex\verb!A.norm(Infinity)!} largest row sum\\
{\ex\verb!A.norm('frob')!} Frobenius norm
\par
%*********************************************
\sect{Matrix Properties}
% Edit (plus/minus) to make columns fit first page
%
{\ex\verb!.is_zero()!};
{\ex\verb!.is_symmetric()!};
{\ex\verb!.is_hermitian()!};\\
%
{\ex\verb!.is_square()!};
{\ex\verb!.is_orthogonal()!};
{\ex\verb!.is_unitary()!};\\
%
{\ex\verb!.is_scalar()!};
{\ex\verb!.is_singular()!};
{\ex\verb!.is_invertible()!};\\
%
{\ex\verb!.is_one()!};
{\ex\verb!.is_nilpotent()!};
{\ex\verb!.is_diagonalizable()!}
\par
%
%
%
%*********************************************
\sect{Eigenvalues and Eigenvectors}
{\warn Note}: Contrast behavior for exact rings (\verb!QQ!) vs.\ \verb!RDF!, \verb!CDF!\\
{\ex\verb!A.charpoly('t')!}  no variable specified defaults to \verb!x!\\
{\ex\verb!  A.characteristic_polynomial() == A.charpoly()!}\\
{\ex\verb!A.fcp('t')!}  factored characteristic polynomial\\
{\ex\verb!A.minpoly()!}  the minimum polynomial\\
{\ex\verb!  A.minimal_polynomial() == A.minpoly()!}\\
{\ex\verb!A.eigenvalues()!} unsorted list, with mutiplicities\\
{\ex\verb!A.eigenvectors_left()!} vectors on left, \verb!_right! too\\
\skipin Returns, per eigenvalue, a triple:
\verb!e!: eigenvalue;\\
\skipin\verb!V!: list of eigenspace basis vectors;
\verb!n!: multiplicity\\
{\ex\verb!A.eigenmatrix_right()!} vectors on right, \verb!_left! too\\
\skipin Returns pair:\quad \verb!D!: diagonal matrix with eigenvalues\\
\skipin\verb!P!: eigenvectors as columns (rows for left version)\\
\skipin\skipin with zero columns if matrix not diagonalizable\\
Eigenspaces: see ``Constructing Subspaces''
\par
%*********************************************
\sect{Decompositions}
%
{\warn Note}: availability depends on base ring of matrix,\\
\skipin try \verb!RDF! or \verb!CDF! for numerical work, \verb!QQ! for exact\\
\skipin ``unitary'' is ``orthogonal'' in real case\\
{\ex\verb!A.jordan_form(transformation=True)!}\\
\skipin returns a pair of matrices with: \verb!A == P^(-1)*J*P!\\
\skipin\skipin\verb!J!: matrix of Jordan blocks for eigenvalues\\
\skipin\skipin\verb!P!: nonsingular matrix\\
%
{\ex\verb!A.smith_form()!} triple with: \verb!D == U*A*V!\\
\skipin\verb!D!: elementary divisors on diagonal\\
\skipin\verb!U, V!: with unit determinant\\
%
{\ex\verb!A.LU()!} triple with: \verb!P*A == L*U!\\
\skipin\verb!P!: a permutation matrix\\
\skipin\verb!L!: lower triangular matrix,\quad\verb!U!: upper triangular matrix\\
%
{\ex\verb!A.QR()!} pair with: \verb!A == Q*R!\\
\skipin\verb!Q!: a unitary matrix,\quad\verb!R!: upper triangular matrix\\
%
{\ex\verb!A.SVD()!} triple with: \verb!A == U*S*(V-conj-transpose)!\\
\skipin\verb!U!: a unitary matrix\\
\skipin\verb!S!: zero off the diagonal, dimensions same as \verb!A!\\
\skipin\verb!V!: a unitary matrix\\
%
{\ex\verb!A.schur()!} pair with: \verb!A == Q*T*(Q-conj-transpose)!\\
\skipin\verb!Q!: a unitary matrix\\
\skipin\verb!T!: upper-triangular matrix, maybe $2\times2$ diagonal blocks\\
%
{\ex\verb!A.rational_form()!}, aka Frobenius form\\
%
{\ex\verb!A.symplectic_form()!}\\
{\ex\verb!A.hessenberg_form()!}\\
{\ex\verb!A.cholesky()!} (needs work)
\par
%*********************************************
\sect{Solutions to Systems}
{\ex\verb!A.solve_right(B)!} \verb!_left! too\\
\skipin is solution to \verb!A*X = B!, where \verb!X! is a vector {\bf or} matrix\\
{\ex\verb!A = matrix(QQ, [[1,2],[3,4]])!}\\
{\ex\verb!b = vector(QQ, [3,4])!}, then {\ex\verb!A\b!} is solution {\ex\verb!(-2, 5/2)!}\par
%*********************************************
\sect{Vector Spaces}
{\ex\verb!VectorSpace(QQ, 4)!}  dimension 4, rationals as field\\
{\ex\verb!VectorSpace(RR, 4)!}  ``field'' is 53-bit precision reals\\
{\ex\verb!VectorSpace(RealField(200), 4)!}\\
\skipin ``field'' has 200 bit precision\\
{\ex\verb!CC^4!} 4-dimensional, 53-bit precision complexes\\
{\ex\verb!Y = VectorSpace(GF(7), 4)!}  finite\\
\skipin{\ex\verb!Y.list()!} has $7^4=2401$ vectors
\par
%*********************************************
\sect{Vector Space Properties}
{\ex\verb!V.dimension()!}\\
{\ex\verb!V.basis()!}\\
{\ex\verb!V.echelonized_basis()!}\\
{\ex\verb!V.has_user_basis()!} with non-canonical basis?\\
{\ex\verb!V.is_subspace(W)!} \verb!True! if \verb!W! is a subspace of \verb!V!\\
{\ex\verb!V.is_full()!} rank equals degree (as module)?\\
{\ex\verb!Y = GF(7)^4!},\quad{\ex\verb!T = Y.subspaces(2)!}\\
\skipin\verb!T! is a generator object for 2-D subspaces of \verb!Y!\\
\skipin\verb![U for U in T]! is list of 2850 2-D subspaces of \verb!Y!,\\
\skipin or use \verb!T.next()! to step through subspaces
\par
%*********************************************
\sect{Constructing Subspaces}
{\ex\verb!span([v1,v2,v3], QQ)!} span of list of vectors over ring
\par\vspace*{4pt}
For a matrix \verb!A!, objects returned are\\
\skipin vector spaces when base ring is a field\\
\skipin modules when base ring is just a ring\\
{\ex\verb!A.left_kernel() == A.kernel()!} \verb!right_! too\\
{\ex\verb!A.row_space() == A.row_module()!}\\
{\ex\verb!A.column_space() == A.column_module()!}\\
{\ex\verb!A.eigenspaces_right()!} vectors on right, \verb!_left! too\\
\skipin Pairs: eigenvalues with their right eigenspaces\\
{\ex\verb!A.eigenspaces_right(format='galois')!}\\
\skipin One eigenspace per irreducible factor of char poly
\par\vspace*{4pt}
If \verb!V! and \verb!W! are subspaces\\
{\ex\verb!V.quotient(W)!} quotient of \verb!V! by subspace \verb!W!\\
{\ex\verb!V.intersection(W)!} intersection of \verb!V! and \verb!W!\\
{\ex\verb!V.direct_sum(W)!} direct sum of \verb!V! and \verb!W!\\
{\ex\verb!V.subspace([v1,v2,v3])!} specify basis vectors in a list
\par
%*********************************************
\sect{Dense versus Sparse}
{\warn Note:} Algorithms may depend on representation\\
Vectors and matrices have two representations\\
\skipin Dense: lists, and lists of lists\\
\skipin Sparse: Python dictionaries\\
{\ex\verb!.is_dense()!}, {\ex\verb!.is_sparse()!}  to check\\
{\ex\verb!A.sparse_matrix()!} returns sparse version of \verb!A!\\
{\ex\verb!A.dense_rows()!} returns dense row vectors of \verb!A!\\
Some commands have  boolean \verb!sparse! keyword
\par
%*********************************************
\sect{Rings}
{\warn Note:} Many algorithms depend on the base ring\\
{\ex\verb!<object>.base_ring(R)!} for vectors, matrices,\dots\\
\skipin to determine the ring in use\\
{\ex\verb!<object>.change_ring(R)!} for vectors, matrices,\dots\\
\skipin to change to the ring (or field), \verb!R!\\
{\ex\verb!R.is_ring()!},\quad{\ex\verb!R.is_field()!},\quad{\ex\verb!R.is_exact()!}\\[2pt]
Some common Sage rings and fields\\
\skipin{\ex\verb!ZZ!}\quad integers, ring\\
\skipin{\ex\verb!QQ!}\quad rationals, field\\
\skipin{\ex\verb!AA!, \verb!QQbar!}\quad algebraic number fields, exact\\
\skipin{\ex\verb!RDF!}\quad real double field, inexact\\
\skipin{\ex\verb!CDF!}\quad complex double field, inexact\\
\skipin{\ex\verb!RR!}\quad 53-bit reals, inexact, not same as {\ex\verb!RDF!}\\
\skipin{\ex\verb!RealField(400)!}\quad 400-bit reals, inexact\\
\skipin{\ex\verb!CC!,\quad\verb!ComplexField(400)!}\quad complexes, too\\
\skipin{\ex\verb!RIF!}\quad real interval field\\
\skipin{\ex\verb!GF(2)!}\quad mod 2, field, specialized implementations\\
\skipin{\ex\verb!GF(p) == FiniteField(p)!}\quad \verb!p! prime, field\\
\skipin{\ex\verb!Integers(6)!}\quad integers mod 6, ring only \\
\skipin{\ex\verb!CyclotomicField(7)!}\quad rationals with 7$^{\rm th}$ root of unity\\
\skipin{\ex\verb!QuadraticField(-5, 'x')!}\quad rationals with \verb!x=!$\sqrt{-5}$\\
\skipin{\ex\verb!SR!}\quad ring of symbolic expressions
\par
%*********************************************
\sect{Vector Spaces versus Modules}
Module ``is'' a vector space over a ring, rather than a field\\
Many commands above apply to modules\\
Some ``vectors'' are really module elements
\par
%*********************************************
\sect{More Help}
``tab-completion'' on partial commands\\
``tab-completion'' on \verb!<object.>! for all relevant methods\\
\verb!<command>?! for summary and examples\\
\verb!<command>??! for complete source code
%
\end{multicols*}

\end{document}
