-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add BLOCK-DIAG, MAP-BLOCKS, and PARTIAL-TRACE #104
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -219,6 +219,11 @@ ELEMENT-TYPE, CAST, COPY-TENSOR, DEEP-COPY-TENSOR, TREF, SETF TREF)" | |
"Whether MATRIX is a unitary matrix" | ||
(= matrix (conjugate-transpose matrix) epsilon)) | ||
|
||
(defun block-matrix-p (matrix) | ||
(and (square-matrix-p matrix) | ||
(let ((dim (nrows matrix))) | ||
(cl:= dim (expt (isqrt dim) 2))))) | ||
|
||
(defmacro assert-square-matrix (&rest matrices) | ||
`(progn | ||
,@(loop :for matrix in matrices | ||
|
@@ -379,6 +384,17 @@ If fast is t then just change layout. Fast can cause problems when you want to m | |
(loop :for i :below rows | ||
:collect (tref matrix i i)))))) | ||
|
||
(defgeneric block-diag (matrix) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same thing here -- seems like you have in mind specifically 2x2 block decompositions. |
||
(:documentation "Get a list of the diagonal block elements of MATRIX") | ||
(:method ((matrix matrix)) | ||
(policy-cond:with-expectations (> speed safety) | ||
((assertion (block-matrix-p matrix))) | ||
(let* ((dim (floor (sqrt (nrows matrix))))) | ||
(loop :for i :from 0 :below dim | ||
:for from := (list (* i dim) (* i dim)) | ||
:for to := (list (* (1+ i) dim) (* (1+ i) dim)) | ||
:collect (slice matrix from to)))))) | ||
|
||
(defgeneric trace (matrix) | ||
(:documentation "Get the trace of MATRIX (sum of diagonals)") | ||
(:method ((matrix matrix)) | ||
|
@@ -387,6 +403,24 @@ If fast is t then just change layout. Fast can cause problems when you want to m | |
(loop :for i :below (nrows matrix) | ||
:sum (tref matrix i i))))) | ||
|
||
(defgeneric map-blocks (function matrix &key type) | ||
(:documentation "Map FUNCTION over the NxN blocks of the N²xN² MATRIX, returning a fresh matrix of dimension NxN.") | ||
(:method (function (matrix matrix) &key (type (element-type matrix))) | ||
(policy-cond:with-expectations (> speed safety) | ||
((assertion (block-matrix-p matrix))) | ||
(let* ((dim (floor (sqrt (nrows matrix)))) | ||
(freiche (zeros (list dim dim) :type type))) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yum |
||
(loop :for i :from 0 :below dim :do | ||
(loop :for j :from 0 :below dim :do | ||
(let ((from (list (* i dim) (* j dim))) | ||
(to (list (* (1+ i) dim) (* (1+ j) dim)))) | ||
(setf (tref freiche i j) | ||
(funcall function (slice matrix from to)))))) | ||
freiche)))) | ||
|
||
(defun partial-trace (matrix) | ||
(map-blocks #'trace matrix)) | ||
|
||
(defgeneric det (matrix) | ||
(:documentation "Compute the determinant of a square matrix MATRIX") | ||
(:method ((matrix matrix)) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,6 +73,7 @@ | |
|
||
#:map | ||
#:map! | ||
#:map-blocks | ||
|
||
#:reshape | ||
#:slice | ||
|
@@ -136,6 +137,7 @@ | |
#:scale | ||
#:scale! | ||
#:diag | ||
#:block-diag | ||
#:det | ||
#:upper-triangular | ||
#:lower-triangular | ||
|
@@ -146,6 +148,7 @@ | |
#:orthonormalize | ||
#:orthonormalize! | ||
#:trace | ||
#:partial-trace | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. gotem |
||
#:direct-sum | ||
#:conjugate-transpose | ||
#:conjugate-transpose! | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: the general usage is that a "block matrix" is a matrix with an associated decomposition, e.g.
would be a valid block decomposition if
nrows(A) = nrows(B) = nrows(C)
,ncols(A) = ncols(D)
, and so on. In this usage, the matrix doesn't have to be square. I'd suggest changing the name of your defun and adding a docstring if you want to keep the current behavior.