Skip to content
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

Cholesky Function updated at 4 location -- PR for issue #23048 #23166

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 81 additions & 2 deletions ivy/functional/backends/jax/linear_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,87 @@
backend_version,
)
def cholesky(
x: JaxArray, /, *, upper: bool = False, out: Optional[JaxArray] = None
) -> JaxArray:
x: Union[jnp.DeviceArray, jnp.ShapedArray],
/,
*,
upper: bool = False,
out: Optional[jnp.DeviceArray] = None,
) -> jnp.DeviceArray:
"""
Compute the Cholesky decomposition of the x matrix.

Parameters
----------
x : jnp.DeviceArray or jnp.ShapedArray
Input array having shape (..., M, M) and whose innermost two dimensions form
square symmetric positive-definite matrices. Should have a floating-point data
type.
upper : bool, optional
If True, the result must be the upper-triangular Cholesky factor U. If False,
the result must be the lower-triangular Cholesky factor L. Default: False.
out : jnp.DeviceArray, optional
Optional output array, for writing the result to. It must have a shape that the
inputs broadcast to.

Returns
-------
jnp.DeviceArray
An array containing the Cholesky factors for each square matrix. If upper is
False, the returned array must contain lower-triangular matrices; otherwise, the
returned array must contain upper-triangular matrices. The returned array must
have a floating-point data type determined by Type Promotion Rules and must have
the same shape as x.

Examples
--------
With jnp.DeviceArray input:

>>> x = jnp.array([[4.0, 1.0, 2.0, 0.5, 2.0],
... [1.0, 0.5, 0.0, 0.0, 0.0],
... [2.0, 0.0, 3.0, 0.0, 0.0],
... [0.5, 0.0, 0.0, 0.625, 0.0],
... [2.0, 0.0, 0.0, 0.0, 16.0]])
>>> l = cholesky(x, upper=False)
>>> print(l)
jnp.array([[ 2. , 0.5 , 1. , 0.25, 1. ],
[ 0. , 0.5 , -1. , -0.25, -1. ],
[ 0. , 0. , 1. , -0.5 , -2. ],
[ 0. , 0. , 0. , 0.5 , -3. ],
[ 0. , 0. , 0. , 0. , 1. ]])

>>> x = jnp.array([[4.0, 1.0, 2.0, 0.5, 2.0],
... [1.0, 0.5, 0.0, 0.0, 0.0],
... [2.0, 0.0, 3.0, 0.0, 0.0],
... [0.5, 0.0, 0.0, 0.625, 0.0],
... [2.0, 0.0, 0.0, 0.0, 16.0]])
>>> y = jnp.zeros([5, 5])
>>> cholesky(x, upper=False, out=y)
>>> print(y)
jnp.array([[ 2. , 0.5 , 1. , 0.25, 1. ],
[ 0. , 0.5 , -1. , -0.25, -1. ],
[ 0. , 0. , 1. , -0.5 , -2. ],
[ 0. , 0. , 0. , 0.5 , -3. ],
[ 0. , 0. , 0. , 0. , 1. ]])

>>> x = jnp.array([[4.0, 1.0, 2.0, 0.5, 2.0],
... [1.0, 0.5, 0.0, 0.0, 0.0],
... [2.0, 0.0, 3.0, 0.0, 0.0],
... [0.5, 0.0, 0.0, 0.625, 0.0],
... [2.0, 0.0, 0.0, 0.0, 16.0]])
>>> cholesky(x, upper=False, out=x)
>>> print(x)
jnp.array([[ 2. , 0.5 , 1. , 0.25, 1. ],
[ 0. , 0.5 , -1. , -0.25, -1. ],
[ 0. , 0. , 1. , -0.5 , -2. ],
[ 0. , 0. , 0. , 0.5 , -3. ],
[ 0. , 0. , 0. , 0. , 1. ]])

>>> x = jnp.array([[1., -2.], [2., 5.]])
>>> u = cholesky(x, upper=False)
>>> print(u)
jnp.array([[ 1., -2.],
[ 0., 1.]])
"""
if not upper:
ret = jnp.linalg.cholesky(x)
else:
Expand Down
75 changes: 75 additions & 0 deletions ivy/functional/backends/numpy/linear_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,81 @@
def cholesky(
x: np.ndarray, /, *, upper: bool = False, out: Optional[np.ndarray] = None
) -> np.ndarray:
"""
Compute the Cholesky decomposition of the x matrix.

Parameters
----------
x : np.ndarray
Input array having shape (..., M, M) and whose innermost two dimensions form
square symmetric positive-definite matrices. Should have a floating-point data
type.
upper : bool, optional
If True, the result must be the upper-triangular Cholesky factor U. If False,
the result must be the lower-triangular Cholesky factor L. Default: False.
out : np.ndarray, optional
Optional output array, for writing the result to. It must have a shape that the
inputs broadcast to.

Returns
-------
np.ndarray
An array containing the Cholesky factors for each square matrix. If upper is
False, the returned array must contain lower-triangular matrices; otherwise, the
returned array must contain upper-triangular matrices. The returned array must
have a floating-point data type determined by Type Promotion Rules and must have
the same shape as x.

Examples
--------
With np.ndarray input:

>>> x = np.array([[4.0, 1.0, 2.0, 0.5, 2.0],
... [1.0, 0.5, 0.0, 0.0, 0.0],
... [2.0, 0.0, 3.0, 0.0, 0.0],
... [0.5, 0.0, 0.0, 0.625, 0.0],
... [2.0, 0.0, 0.0, 0.0, 16.0]])
>>> l = cholesky(x, upper=False)
>>> print(l)
np.array([[ 2. , 0.5 , 1. , 0.25, 1. ],
[ 0. , 0.5 , -1. , -0.25, -1. ],
[ 0. , 0. , 1. , -0.5 , -2. ],
[ 0. , 0. , 0. , 0.5 , -3. ],
[ 0. , 0. , 0. , 0. , 1. ]])

>>> x = np.array([[4.0, 1.0, 2.0, 0.5, 2.0],
... [1.0, 0.5, 0.0, 0.0, 0.0],
... [2.0, 0.0, 3.0, 0.0, 0.0],
... [0.5, 0.0, 0.0, 0.625, 0.0],
... [2.0, 0.0, 0.0, 0.0, 16.0]])
>>> y = np.zeros([5, 5])
>>> cholesky(x, upper=False, out=y)
>>> print(y)
np.array([[ 2. , 0.5 , 1. , 0.25, 1. ],
[ 0. , 0.5 , -1. , -0.25, -1. ],
[ 0. , 0. , 1. , -0.5 , -2. ],
[ 0. , 0. , 0. , 0.5 , -3. ],
[ 0. , 0. , 0. , 0. , 1. ]])

>>> x = np.array([[4.0, 1.0, 2.0, 0.5, 2.0],
... [1.0, 0.5, 0.0, 0.0, 0.0],
... [2.0, 0.0, 3.0, 0.0, 0.0],
... [0.5, 0.0, 0.0, 0.625, 0.0],
... [2.0, 0.0, 0.0, 0.0, 16.0]])
>>> cholesky(x, upper=False, out=x)
>>> print(x)
np.array([[ 2. , 0.5 , 1. , 0.25, 1. ],
[ 0. , 0.5 , -1. , -0.25, -1. ],
[ 0. , 0. , 1. , -0.5 , -2. ],
[ 0. , 0. , 0. , 0.5 , -3. ],
[ 0. , 0. , 0. , 0. , 1. ]])

>>> x = np.array([[1., -2.], [2., 5.]])
>>> u = cholesky(x, upper=False)
>>> print(u)
np.array([[ 1., -2.],
[ 0., 1.]])
"""
if not upper:
ret = np.linalg.cholesky(x)
else:
Expand Down
83 changes: 79 additions & 4 deletions ivy/functional/backends/torch/linear_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,82 @@
def cholesky(
x: torch.Tensor, /, *, upper: bool = False, out: Optional[torch.Tensor] = None
) -> torch.Tensor:
"""
Compute the Cholesky decomposition of the x matrix.

Parameters
----------
x : torch.Tensor
Input tensor having shape (..., M, M) and whose innermost two dimensions form
square symmetric positive-definite matrices. Should have a floating-point data
type.
upper : bool, optional
If True, the result must be the upper-triangular Cholesky factor U. If False,
the result must be the lower-triangular Cholesky factor L. Default: False.
out : torch.Tensor, optional
Optional output tensor, for writing the result to. It must have a shape that the
inputs broadcast to.

Returns
-------
torch.Tensor
A tensor containing the Cholesky factors for each square matrix. If upper is
False, the returned tensor must contain lower-triangular matrices; otherwise, the
returned tensor must contain upper-triangular matrices. The returned tensor must
have a floating-point data type and the same shape as x.

Examples
--------
With torch.Tensor input:

>>> x = torch.tensor([[4.0, 1.0, 2.0, 0.5, 2.0],
... [1.0, 0.5, 0.0, 0.0, 0.0],
... [2.0, 0.0, 3.0, 0.0, 0.0],
... [0.5, 0.0, 0.0, 0.625, 0.0],
... [2.0, 0.0, 0.0, 0.0, 16.0]])
>>> l = cholesky(x, upper=False)
>>> print(l)
torch.Tensor([[ 2. , 0.5 , 1. , 0.25, 1. ],
[ 0. , 0.5 , -1. , -0.25, -1. ],
[ 0. , 0. , 1. , -0.5 , -2. ],
[ 0. , 0. , 0. , 0.5 , -3. ],
[ 0. , 0. , 0. , 0. , 1. ]])

>>> x = torch.tensor([[4.0, 1.0, 2.0, 0.5, 2.0],
... [1.0, 0.5, 0.0, 0.0, 0.0],
... [2.0, 0.0, 3.0, 0.0, 0.0],
... [0.5, 0.0, 0.0, 0.625, 0.0],
... [2.0, 0.0, 0.0, 0.0, 16.0]])
>>> y = torch.zeros([5, 5])
>>> cholesky(x, upper=False, out=y)
>>> print(y)
torch.Tensor([[ 2. , 0.5 , 1. , 0.25, 1. ],
[ 0. , 0.5 , -1. , -0.25, -1. ],
[ 0. , 0. , 1. , -0.5 , -2. ],
[ 0. , 0. , 0. , 0.5 , -3. ],
[ 0. , 0. , 0. , 0. , 1. ]])

>>> x = torch.tensor([[4.0, 1.0, 2.0, 0.5, 2.0],
... [1.0, 0.5, 0.0, 0.0, 0.0],
... [2.0, 0.0, 3.0, 0.0, 0.0],
... [0.5, 0.0, 0.0, 0.625, 0.0],
... [2.0, 0.0, 0.0, 0.0, 16.0]])
>>> cholesky(x, upper=False, out=x)
>>> print(x)
torch.Tensor([[ 2. , 0.5 , 1. , 0.25, 1. ],
[ 0. , 0.5 , -1. , -0.25, -1. ],
[ 0. , 0. , 1. , -0.5 , -2. ],
[ 0. , 0. , 0. , 0.5 , -3. ],
[ 0. , 0. , 0. , 0. , 0. , 1. ]])

>>> x = torch.tensor([[1., -2.], [2., 5.]])
>>> u = cholesky(x, upper=False)
>>> print(u)
torch.Tensor([[ 1., -2.],
[ 0., 1.]])
"""
if not upper:
return torch.linalg.cholesky(x, out=out)
ret = torch.linalg.cholesky(x, out=out)
else:
ret = torch.transpose(
torch.linalg.cholesky(
Expand All @@ -35,9 +109,10 @@ def cholesky(
dim0=len(x.shape) - 1,
dim1=len(x.shape) - 2,
)
if ivy.exists(out):
return ivy.inplace_update(out, ret)
return ret
if out is not None:
out.copy_(ret)
return out
return ret


cholesky.support_native_out = True
Expand Down
Loading
Loading