diff --git a/pytensor/tensor/nlinalg.py b/pytensor/tensor/nlinalg.py index dd9b132af4..2ccc1c5930 100644 --- a/pytensor/tensor/nlinalg.py +++ b/pytensor/tensor/nlinalg.py @@ -42,7 +42,11 @@ def make_node(self, x): out_dtype = "float64" else: out_dtype = x.dtype - return Apply(self, [x], [matrix(shape=x.type.shape, dtype=out_dtype)]) + return Apply( + self, + [x], + [matrix(shape=(x.type.shape[1], x.type.shape[0]), dtype=out_dtype)], + ) def perform(self, node, inputs, outputs): (x,) = inputs diff --git a/tests/tensor/test_nlinalg.py b/tests/tensor/test_nlinalg.py index 0aea17af7e..a9624fd47d 100644 --- a/tests/tensor/test_nlinalg.py +++ b/tests/tensor/test_nlinalg.py @@ -70,6 +70,21 @@ def test_pseudoinverse_grad(): utt.verify_grad(pinv, [r]) +def test_pseudoinverse_static_shape(): + x = matrix(shape=(3, 5)) + z = pinv(x) + assert z.type.shape == (5, 3) + + g = pytensor.grad(z.sum(), x) + f = function([x], g) + + rng = np.random.default_rng(utt.fetch_seed()) + r = rng.standard_normal((3, 5)).astype(config.floatX) + assert f(r).shape == (3, 5) + + utt.verify_grad(pinv, [r]) + + class TestMatrixInverse(utt.InferShapeTester): def setup_method(self): super().setup_method()