提交 6d431aa6 authored 作者: David Horsley's avatar David Horsley 提交者: Ricardo Vieira

Move linalg rewrites, delete sandbox

Moving caused a circular dependency with tensor.blas. It seems most linalg rewrites are in the stablize set, so should run before the blas specializers anyway, so these checks were removed. This also deleted the unused `spectral_radius_bound` and dummy `Minimal(Op)`.
上级 c655b028
from pytensor.sandbox.linalg.ops import spectral_radius_bound
import numpy as np
from pytensor.graph.basic import Apply
from pytensor.graph.op import Op
from pytensor.tensor.type import lscalar
class Minimal(Op):
# TODO : need description for class
# if the Op has any attributes, consider using them in the eq function.
# If two Apply nodes have the same inputs and the ops compare equal...
# then they will be MERGED so they had better have computed the same thing!
__props__ = ()
def __init__(self):
# If you put things here, think about whether they change the outputs
# computed by # self.perform()
# - If they do, then you should take them into consideration in
# __eq__ and __hash__
# - If they do not, then you should not use them in
# __eq__ and __hash__
super().__init__()
def make_node(self, *args):
# HERE `args` must be PYTENSOR VARIABLES
return Apply(op=self, inputs=args, outputs=[lscalar()])
def perform(self, node, inputs, out_):
(output,) = out_
# HERE `inputs` are PYTHON OBJECTS
# do what you want here,
# but do not modify any of the arguments [inplace].
print("perform got %i arguments" % len(inputs))
print("Max of input[0] is ", np.max(inputs[0]))
# return some computed value.
# do not return something that is aliased to one of the inputs.
output[0] = np.asarray(0, dtype="int64")
minimal = Minimal()
......@@ -7,6 +7,7 @@ import pytensor.tensor.rewriting.extra_ops
# Register JAX specializations
import pytensor.tensor.rewriting.jax
import pytensor.tensor.rewriting.linalg
import pytensor.tensor.rewriting.math
import pytensor.tensor.rewriting.shape
import pytensor.tensor.rewriting.special
......
import numpy as np
import pytest
from pytensor import function
from pytensor.sandbox.minimal import minimal
from pytensor.tensor.type import matrix, vector
from tests import unittest_tools as utt
@pytest.mark.skip(reason="Unfinished test")
class TestMinimal:
"""
TODO: test dtype conversion
TODO: test that invalid types are rejected by make_node
TODO: test that each valid type for A and b works correctly
"""
def setup_method(self):
self.rng = np.random.default_rng(utt.fetch_seed(666))
def test_minimal(self):
A = matrix()
b = vector()
print("building function")
f = function([A, b], minimal(A, A, b, b, A))
print("built")
Aval = self.rng.standard_normal((5, 5))
bval = np.arange(5, dtype=float)
f(Aval, bval)
print("done")
......@@ -5,10 +5,10 @@ import pytensor
from pytensor import function
from pytensor import tensor as at
from pytensor.configdefaults import config
from pytensor.sandbox.linalg.ops import inv_as_solve, spectral_radius_bound
from pytensor.tensor.elemwise import DimShuffle
from pytensor.tensor.math import _allclose
from pytensor.tensor.nlinalg import MatrixInverse, matrix_inverse
from pytensor.tensor.rewriting.linalg import inv_as_solve
from pytensor.tensor.slinalg import Cholesky, Solve, solve
from pytensor.tensor.type import dmatrix, matrix, vector
from tests import unittest_tools as utt
......@@ -65,53 +65,6 @@ def test_rop_lop():
assert _allclose(v1, v2), f"LOP mismatch: {v1} {v2}"
def test_spectral_radius_bound():
tol = 10 ** (-6)
rng = np.random.default_rng(utt.fetch_seed())
x = matrix()
radius_bound = spectral_radius_bound(x, 5)
f = pytensor.function([x], radius_bound)
shp = (3, 4)
m = rng.random(shp)
m = np.cov(m).astype(config.floatX)
radius_bound_pytensor = f(m)
# test the approximation
mm = m
for i in range(5):
mm = np.dot(mm, mm)
radius_bound_numpy = np.trace(mm) ** (2 ** (-5))
assert abs(radius_bound_numpy - radius_bound_pytensor) < tol
# test the bound
eigen_val = numpy.linalg.eig(m)
assert (eigen_val[0].max() - radius_bound_pytensor) < tol
# test type errors
xx = vector()
ok = False
try:
spectral_radius_bound(xx, 5)
except TypeError:
ok = True
assert ok
ok = False
try:
spectral_radius_bound(x, 5.0)
except TypeError:
ok = True
assert ok
# test value error
ok = False
try:
spectral_radius_bound(x, -5)
except ValueError:
ok = True
assert ok
def test_transinv_to_invtrans():
X = matrix("X")
Y = matrix_inverse(X)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论