def test_symbol(): xt = theano_code(x) assert isinstance(xt, (tt.TensorVariable, ts.ScalarVariable)) assert xt.name == x.name assert theano_code(x, broadcastables={x: (False,)}).broadcastable == (False,) assert theano_code(x, broadcastables={x: (False,)}).name == x.name
def test_MatrixSlice(): n = sympy.Symbol('n', integer=True) X = sympy.MatrixSymbol('X', n, n) Y = X[1:2:3, 4:5:6] Yt = theano_code(Y) from theano.scalar import Scalar from theano import Constant s = Scalar('int64') assert tuple(Yt.owner.op.idx_list) == (slice(s, s, s), slice(s, s, s)) assert Yt.owner.inputs[0] == theano_code(X) # == doesn't work in theano like it does in SymPy. You have to use # equals. assert [i.equals(j) for i, j in zip(Yt.owner.inputs[1:],[ Constant(s, 1), Constant(s, 2), Constant(s, 3), Constant(s, 4), Constant(s, 5), Constant(s, 6), ])] k = sympy.Symbol('k') kt = theano_code(k, dtypes={k: 'int32'}) start, stop, step = 4, k, 2 Y = X[start:stop:step] Yt = theano_code(Y, dtypes={n: 'int32', k: 'int32'})
def test_complexfunctions(): xt, yt = theano_code(x, dtypes={x:'complex128'}), theano_code(y, dtypes={y: 'complex128'}) from sympy import conjugate from theano.tensor import as_tensor_variable as atv from theano.tensor import complex as cplx assert theq(theano_code(y*conjugate(x)), yt*(xt.conj())) assert theq(theano_code((1+2j)*x), xt*(atv(1.0)+atv(2.0)*cplx(0,1)))
def test_add(): expr = x + y comp = theano_code(expr) assert comp.owner.op == theano.tensor.add comp = theano_code(expr, broadcastables={x: (False,), y: (False,)}) assert comp.broadcastable == (False,) comp = theano_code(expr, broadcastables={x: (False, True), y: (False, False)}) assert comp.broadcastable == (False, False)
def test_Piecewise(): # A piecewise linear xt, yt = theano_code(x), theano_code(y) expr = sy.Piecewise((0, x < 0), (x, x < 2), (1, True)) # ___/III result = theano_code(expr) assert result.owner.op == tt.switch expected = tt.switch(xt < 0, 0, tt.switch(xt < 2, xt, 1)) assert theq(result, expected) expr = sy.Piecewise((x, x < 0)) result = theano_code(expr) expected = tt.switch(xt < 0, xt, np.nan) assert theq(result, expected)
def test_MatrixSlice(): n = sympy.Symbol('n', integer=True) X = sympy.MatrixSymbol('X', n, n) Y = X[1:2:3, 4:5:6] Yt = theano_code(Y) assert tuple(Yt.owner.op.idx_list) == (slice(1, 2, 3), slice(4, 5, 6)) assert Yt.owner.inputs[0] == theano_code(X) k = sympy.Symbol('k') kt = theano_code(k, dtypes={k: 'int32'}) start, stop, step = 4, k, 2 Y = X[start:stop:step] Yt = theano_code(Y, dtypes={n: 'int32', k: 'int32'})
def test_MatrixSlice(): n = sympy.Symbol('n', integer=True) X = sympy.MatrixSymbol('X', n, n) Y = X[1:2:3, 4:5:6] Yt = theano_code(Y) assert tuple(Yt.owner.op.idx_list) == (slice(1,2,3), slice(4,5,6)) assert Yt.owner.inputs[0] == theano_code(X) k = sympy.Symbol('k') kt = theano_code(k, dtypes={k: 'int32'}) start, stop, step = 4, k, 2 Y = X[start:stop:step] Yt = theano_code(Y, dtypes={n: 'int32', k: 'int32'})
def test_Piecewise(): # A piecewise linear xt, yt = theano_code(x), theano_code(y) expr = sy.Piecewise((0, x<0), (x, x<2), (1, True)) # ___/III result = theano_code(expr) assert result.owner.op == tt.switch expected = tt.switch(xt<0, 0, tt.switch(xt<2, xt, 1)) assert theq(result, expected) expr = sy.Piecewise((x, x < 0)) result = theano_code(expr) expected = tt.switch(xt < 0, xt, np.nan) assert theq(result, expected)
def test_add(): expr = x + y comp = theano_code(expr) assert comp.owner.op == theano.tensor.add comp = theano_code(expr, broadcastables={x: (False, ), y: (False, )}) assert comp.broadcastable == (False, ) comp = theano_code(expr, broadcastables={ x: (False, True), y: (False, False) }) assert comp.broadcastable == (False, False)
def test_global_cache(): """ Test use of the global cache. """ from sympy.printing.theanocode import global_cache backup = dict(global_cache) try: # Temporarily empty global cache global_cache.clear() for s in [x, X, f_t]: st = theano_code(s) assert theano_code(s) is st finally: # Restore global cache global_cache.update(backup)
def test_DenseMatrix(): t = sy.Symbol('theta') for MatrixType in [sy.Matrix, sy.ImmutableMatrix]: X = MatrixType([[sy.cos(t), -sy.sin(t)], [sy.sin(t), sy.cos(t)]]) tX = theano_code(X) assert isinstance(tX, tt.TensorVariable) assert tX.owner.op == tt.join
def test_BlockMatrix(): n = sympy.Symbol('n', integer=True) A = sympy.MatrixSymbol('A', n, n) B = sympy.MatrixSymbol('B', n, n) C = sympy.MatrixSymbol('C', n, n) D = sympy.MatrixSymbol('D', n, n) At, Bt, Ct, Dt = map(theano_code, (A, B, C, D)) Block = sympy.BlockMatrix([[A, B], [C, D]]) Blockt = theano_code(Block) solutions = [tt.join(0, tt.join(1, At, Bt), tt.join(1, Ct, Dt)), tt.join(1, tt.join(0, At, Ct), tt.join(0, Bt, Dt))] assert any(theq(Blockt, solution) for solution in solutions)
def test_cache_types_distinct(): """ Test that symbol-like objects of different types (Symbol, MatrixSymbol, AppliedUndef) are distinguished by the cache even if they have the same name. """ symbols = [sy.Symbol('f_t'), sy.MatrixSymbol('f_t', 4, 4), f_t] cache = {} # Single shared cache printed = {} for s in symbols: st = theano_code_(s, cache=cache) assert st not in printed.values() printed[s] = st # Check all printed objects are distinct assert len(set(map(id, printed.values()))) == len(symbols) # Check retrieving for s, st in printed.items(): assert theano_code(s, cache=cache) is st
def test_many(): expr = sy.exp(x**2 + sy.cos(y)) * sy.log(2*z) comp = theano_code(expr) expected = tt.exp(xt**2 + tt.cos(yt)) * tt.log(2*zt)
def theano_code_(expr, **kwargs): """ Wrapper for theano_code that uses a new, empty cache by default. """ kwargs.setdefault('cache', {}) with warns_deprecated_sympy(): return theano_code(expr, **kwargs)
def test_AppliedUndef(): t = sy.Symbol('t') f = sy.Function('f') ft = theano_code(f(t)) assert isinstance(ft, tt.TensorVariable) assert ft.name == 'f_t'
def test_Derivative(): assert theq(theano_code(sy.Derivative(sy.sin(x), x, evaluate=False)), theano.grad(tt.sin(xt), xt))
def theano_code_(expr, **kwargs): """ Wrapper for theano_code that uses a new, empty cache by default. """ kwargs.setdefault('cache', {}) return theano_code(expr, **kwargs)
def test_Derivative(): simp = lambda expr: theano_simplify(fgraph_of(expr)) assert theq(simp(theano_code(sy.Derivative(sy.sin(x), x, evaluate=False))), simp(theano.grad(tt.sin(xt), xt)))
def test_slice(): assert theano_code(slice(1, 2, 3)) == slice(1, 2, 3) assert str(theano_code(slice(1, x, 3), dtypes={x: 'int32'})) ==\ str(slice(1, xt, 3))
def test_Integers(): assert theano_code(sympy.Integer(3)) == 3
def test_factorial(): n = sympy.Symbol('n') assert theano_code(sympy.factorial(n))
def test_Rationals(): assert theq(theano_code(sympy.Integer(2) / 3), tt.true_div(2, 3)) assert theq(theano_code(S.Half), tt.true_div(1, 2))
def test_cache(): sx = sy.Symbol('x') cache = {} tx = theano_code(sx, cache=cache) assert theano_code(sx, cache=cache) is tx assert theano_code(sx, cache={}) is not tx
def test_Transpose(): X = sympy.MatrixSymbol('X', 4, 4) assert isinstance(theano_code(X.T).owner.op, tt.DimShuffle)
def test_MatrixSymbol(): X = sympy.MatrixSymbol('X', 4, 5) Xt = theano_code(X) assert isinstance(Xt, tt.TensorVariable) assert Xt.broadcastable == (False, False)
def test_Relationals(): xt, yt = theano_code(x), theano_code(y) assert theq(theano_code(x > y), xt > yt) assert theq(theano_code(x < y), xt < yt) assert theq(theano_code(x >= y), xt >= yt) assert theq(theano_code(x <= y), xt <= yt)
def test_trig(): assert theq(theano_code(sympy.sin(x)), tt.sin(xt)) assert theq(theano_code(sympy.tan(x)), tt.tan(xt))
def test_dtype(): assert theano_code(x, dtypes={x: 'float32'}).type.dtype == 'float32' assert theano_code(x, dtypes={x: 'float64'}).type.dtype == 'float64' assert theano_code(x+1, dtypes={x: 'float32'}).type.dtype == 'float32' assert theano_code(x+y, dtypes={x: 'float64', y: 'float32'}).type.dtype == 'float64'
def test_MatMul(): X = sympy.MatrixSymbol('X', 4, 4) Y = sympy.MatrixSymbol('X', 4, 4) Z = sympy.MatrixSymbol('X', 4, 4) expr = X*Y*Z assert isinstance(theano_code(expr).owner.op, tt.Dot)
def test_symbols_are_created_once(): expr = x**x comp = theano_code(expr) assert theq(comp, xt**xt)
def test_MatAdd(): X = sympy.MatrixSymbol('X', 4, 4) Y = sympy.MatrixSymbol('X', 4, 4) Z = sympy.MatrixSymbol('X', 4, 4) expr = X+Y+Z assert isinstance(theano_code(expr).owner.op, tt.Elemwise)