def __init__(self, input_tensor, output_tensor, linear=False, sess=None): self.input_tensor = input_tensor self.output_tensor = output_tensor # TODO: Fix with tensors domain = odl.fn(np.prod(input_tensor.shape.as_list()), dtype=input_tensor.dtype.as_numpy_dtype) range = odl.fn(np.prod(output_tensor.shape.as_list()), dtype=output_tensor.dtype.as_numpy_dtype) self.dx = tf.placeholder(input_tensor.dtype, shape=input_tensor.shape) self.dy = tf.placeholder(output_tensor.dtype, shape=output_tensor.shape) adjoint_of_derivative_tensor = tf.gradients( self.output_tensor, [self.input_tensor], [self.dy])[0] self.adjoint_of_derivative_tensor = (range.weighting.const * adjoint_of_derivative_tensor) # Since tensorflow does not support forward differentiation, use trick # that adjoint of the derivative of adjoint of the derivative is simply # the derivative. derivative_tensor = tf.gradients( adjoint_of_derivative_tensor, [self.dy], [self.dx])[0] self.derivative_tensor = (range.weighting.const * derivative_tensor) if sess is None: self.sess = tf.get_default_session() else: self.sess = sess super(TensorflowOperator, self).__init__(domain, range, linear=linear)
def test_mat_op_init_and_basic_properties(): """Test initialization and basic properties of MatrixOperator.""" # Test default domain and range r2 = odl.rn(2) op_real = MatrixOperator([[1.0, 2], [-1, 0.5]]) assert op_real.domain == r2 assert op_real.range == r2 c2 = odl.cn(2) op_complex = MatrixOperator([[1.0, 2 + 1j], [-1 - 1j, 0.5]]) assert op_complex.domain == c2 assert op_complex.range == c2 int2 = odl.fn(2, dtype=int) op_int = MatrixOperator([[1, 2], [-1, 0]]) assert op_int.domain == int2 assert op_int.range == int2 # Rectangular rect_mat = 2 * np.eye(2, 3) r3 = odl.rn(3) op = MatrixOperator(rect_mat) assert op.domain == r3 assert op.range == r2 MatrixOperator(rect_mat, domain=r3, range=r2) with pytest.raises(ValueError): MatrixOperator(rect_mat, domain=r2, range=r2) with pytest.raises(ValueError): MatrixOperator(rect_mat, domain=r3, range=r3) with pytest.raises(ValueError): MatrixOperator(rect_mat, domain=r2, range=r3) # Rn to Cn okay MatrixOperator(rect_mat, domain=r3, range=odl.cn(2)) # Cn to Rn not okay (no safe cast) with pytest.raises(TypeError): MatrixOperator(rect_mat, domain=odl.cn(3), range=r2) # Complex matrix between real spaces not okay rect_complex_mat = rect_mat + 1j with pytest.raises(TypeError): MatrixOperator(rect_complex_mat, domain=r3, range=r2) # Init with array-like structure (including numpy.matrix) op = MatrixOperator(rect_mat, domain=r3, range=r2) assert isinstance(op.matrix, np.ndarray) op = MatrixOperator(np.asmatrix(rect_mat), domain=r3, range=r2) assert isinstance(op.matrix, np.ndarray) op = MatrixOperator(rect_mat.tolist(), domain=r3, range=r2) assert isinstance(op.matrix, np.ndarray) assert not op.matrix_issparse sparse_mat = _sparse_matrix(odl.rn(5)) op = MatrixOperator(sparse_mat, domain=odl.rn(5), range=odl.rn(5)) assert isinstance(op.matrix, scipy.sparse.spmatrix) assert op.matrix_issparse # Init with uniform_discr space (subclass of FnBase) dom = odl.uniform_discr(0, 1, 3) ran = odl.uniform_discr(0, 1, 2) MatrixOperator(rect_mat, domain=dom, range=ran)