-
Notifications
You must be signed in to change notification settings - Fork 359
Implemented Cholesky decomposition to numpy and tensorflow backends #890
base: master
Are you sure you want to change the base?
Changes from 23 commits
016d654
62a06c0
43952dd
b0f579e
e9f9869
9e16a9f
81b4d8b
195f691
737f071
0fbe8fb
8c37656
a894960
3ba747f
a112ebe
f9fb40d
4b4ece6
0c3817d
aedfe2a
13026b5
11eba6a
4da6eac
6548989
66b5b94
dab2060
e6b9c08
367ce3d
92c931a
a51cb9a
2b269e0
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 |
---|---|---|
|
@@ -122,3 +122,28 @@ def rq( | |
r = np.reshape(r, list(left_dims) + [center_dim]) | ||
q = np.reshape(q, [center_dim] + list(right_dims)) | ||
return r, q | ||
|
||
|
||
def cholesky( | ||
tf: Any, | ||
tensor: Tensor, | ||
pivot_axis: int, | ||
non_negative_diagonal: bool | ||
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. remove 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. (it only makes sense for QR) |
||
) -> Tuple[Tensor, Tensor]: | ||
""" | ||
Computes the Cholesky decomposition of a tensor | ||
|
||
See tensornetwork.backends.tensorflow.decompositions for details. | ||
""" | ||
left_dims = tf.shape(tensor)[:pivot_axis] | ||
right_dims = tf.shape(tensor)[pivot_axis:] | ||
tensor = tf.reshape(tensor, | ||
[tf.reduce_prod(left_dims), | ||
tf.reduce_prod(right_dims)]) | ||
L = tf.linalg.cholesky(tensor) | ||
if non_negative_diagonal: | ||
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. This is unnecessary. The cholesky decomposition should already return a lower-triangular matrix with a real, positive diagonal. |
||
phases = tf.math.sign(tf.linalg.diag_part(L)) | ||
L = phases[:, None] * L | ||
center_dim = tf.shape(L)[1] | ||
L = tf.reshape(L, tf.concat([left_dims, [center_dim]], axis=-1)) | ||
return L |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,6 +52,13 @@ def test_qr(self): | |
q, r = decompositions.qr(np, random_matrix, 1, non_negative_diagonal) | ||
self.assertAllClose(q.dot(r), random_matrix) | ||
|
||
def test_cholesky(self): | ||
#Assured positive-definite hermitian matrixs | ||
random_matrix = [[1.0, 0], [0, 1.0]] | ||
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. Using the identity matrix as "random" matrix is not an ideal test case. You can generate a positive definite matrix e.g. by A = np.random.rand(D,D)
A = A @ A.T.conj() 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. btw. also test this for all supported dtypes 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. do put 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. There is no |
||
for non_negative_diagonal in [True, False]: | ||
L = decompositions.cholesky(tf, random_matrix, 1, non_negative_diagonal) | ||
self.assertAllClose(np.linalg.cholesky(random_matrix), L) | ||
|
||
def test_max_singular_values(self): | ||
random_matrix = np.random.rand(10, 10) | ||
unitary1, _, unitary2 = np.linalg.svd(random_matrix) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -121,6 +121,29 @@ def svd( | |
return u, s, vh, s_rest | ||
|
||
|
||
def cholesky( | ||
torch: Any, | ||
tensor: Tensor, | ||
pivot_axis: int, | ||
non_negative_diagonal: bool = False | ||
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. remove |
||
) -> Tuple[Tensor, Tensor]: | ||
""" | ||
Computes the Cholesky decomposition of a tensor | ||
|
||
See tensornetwork.backends.tensorflow.decompositions for details. | ||
""" | ||
left_dims = np.shape(tensor)[:pivot_axis] | ||
right_dims = np.shape(tensor)[pivot_axis:] | ||
|
||
tensor = torch.reshape(tensor, (np.prod(left_dims), np.prod(right_dims))) | ||
L = torch.cholesky(tensor) | ||
if non_negative_diagonal: | ||
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. remove (see above) |
||
phases = torch.sign(torch.diagonal(L)) | ||
L = phases[:, None] * L | ||
center_dim = L.shape[1] | ||
L = torch.reshape(L, list(left_dims) + [center_dim]) | ||
return L | ||
|
||
def qr( | ||
torch: Any, | ||
tensor: Tensor, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,6 +42,13 @@ def test_expected_shapes_rq(): | |
assert r.shape == (2, 3, 6) | ||
assert q.shape == (6, 4, 5) | ||
|
||
def test_cholesky(): | ||
#Assured positive-definite hermitian matrix | ||
random_matrix = np.array([[1.0, 0], [0, 1.0]]) | ||
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. use better test matrix (see above) |
||
random_matrix = torch.from_numpy(random_matrix) | ||
for non_negative_diagonal in [True, False]: | ||
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. see above |
||
L = decompositions.cholesky(torch, random_matrix, 1, non_negative_diagonal) | ||
np.testing.assert_allclose(torch.cholesky(random_matrix), L) | ||
|
||
def test_rq(): | ||
random_matrix = torch.rand([10, 10], dtype=torch.float64) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -226,3 +226,28 @@ def rq( | |
r = tf.reshape(r, tf.concat([left_dims, [center_dim]], axis=-1)) | ||
q = tf.reshape(q, tf.concat([[center_dim], right_dims], axis=-1)) | ||
return r, q | ||
|
||
|
||
def cholesky( | ||
tf: Any, | ||
tensor: Tensor, | ||
pivot_axis: int, | ||
non_negative_diagonal: bool | ||
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. see above |
||
) -> Tuple[Tensor, Tensor]: | ||
""" Computes de cholesky decomposition of a tensor. | ||
|
||
Returns the Cholesky decomposition of a tensor which we treat as a | ||
square matrix | ||
""" | ||
left_dims = tf.shape(tensor)[:pivot_axis] | ||
right_dims = tf.shape(tensor)[pivot_axis:] | ||
tensor = tf.reshape(tensor, | ||
[tf.reduce_prod(left_dims), | ||
tf.reduce_prod(right_dims)]) | ||
L = tf.linalg.cholesky(tensor) | ||
if non_negative_diagonal: | ||
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. see above |
||
phases = tf.math.sign(tf.linalg.diag_part(L)) | ||
L = phases[:, None] * L | ||
center_dim = tf.shape(L)[1] | ||
L = tf.reshape(L, tf.concat([left_dims, [center_dim]], axis=-1)) | ||
return L | ||
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. add a newline here (at the end of the file) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,6 +54,13 @@ def test_qr(self): | |
q, r = decompositions.qr(tf, random_matrix, 1, non_negative_diagonal) | ||
self.assertAllClose(tf.tensordot(q, r, ([1], [0])), random_matrix) | ||
|
||
def test_cholesky(self): | ||
#Assured positive-definite hermitian matrix | ||
random_matrix = [[1.0, 0], [0, 1.0]] | ||
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. modify test, see above |
||
for non_negative_diagonal in [True, False]: | ||
L = decompositions.cholesky(tf, random_matrix, 1, non_negative_diagonal) | ||
self.assertAllClose(np.linalg.cholesky(random_matrix), L) | ||
|
||
def test_rq_defun(self): | ||
random_matrix = np.random.rand(10, 10) | ||
for non_negative_diagonal in [True, False]: | ||
|
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.
Rename
tf
tonp
(the user passes thenumpy
module here)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.
ya