Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
# Trigonometric functions can be computed, along with their gradients.


cos = odl.ufunc_ops.cos()
sin = odl.ufunc_ops.sin()
cos = odl.oplib.cos()
sin = odl.oplib.sin()

# Compute cosine and its gradient

Expand All @@ -18,16 +18,15 @@
# Other functions include the square, exponential, etc
# Higher order derivatives are obtained via the gradient of the gradient, etc.

square = odl.ufunc_ops.square()
square = odl.oplib.square()

print('[x^2](3) = {}, [d/dx x^2](3) = {}, '
'[d^2/dx^2 x^2](3) = {}, [d^3/dx^3 x^2](3) = {}'
''.format(square(3), square.gradient(3),
square.gradient.gradient(3),
''.format(square(3), square.gradient(3), square.gradient.gradient(3),
square.gradient.gradient.gradient(3)))

# Can also define ufuncs on vector-spaces, then they act pointwise.

r3 = odl.rn(3)
exp_r3 = odl.ufunc_ops.exp(r3)
exp_r3 = odl.oplib.exp(r3)
print('e^[1, 2, 3] = {}'.format(exp_r3([1, 2, 3])))
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import odl

# Create square functional. It's domain is by default the real numbers.
square = odl.ufunc_ops.square()
square = odl.oplib.square()

# Create L2 norm functionals
space = odl.rn(3)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# Create space and functionals
r2 = odl.rn(2)
rosenbrock = odl.solvers.RosenbrockFunctional(r2, scale=2.0)
log = odl.ufunc_ops.log()
log = odl.oplib.log()

# Create goal functional by composing log with rosenbrock and add 0.1 to
# avoid singularity at 0
Expand Down
57 changes: 57 additions & 0 deletions examples/space/auto_weighting.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"""Example demonstrating the usage of the ``auto_weighting`` decorator."""

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads more like a test than an example, is it possible to make it easier on the eyes?


import odl
from odl.space.space_utils import auto_weighting


class ScalingOp(odl.Operator):

"""Operator that scales input by a constant."""

def __init__(self, dom, ran, c):
super(ScalingOp, self).__init__(dom, ran, linear=True)
self.c = c

def _call(self, x):
return self.c * x

@property
@auto_weighting
def adjoint(self):
return ScalingOp(self.range, self.domain, self.c)


rn = odl.rn(2) # Constant weight 1
discr = odl.uniform_discr(0, 4, 2) # Constant weight 2
print('*** Spaces ***')
print('Rn =', rn, '- weight =', rn.weighting.const)
print('discr =', discr, '- weight =', discr.weighting.const)
print('')

op1 = ScalingOp(rn, rn, 2) # Same weightings, no scaling in adjoint
op2 = ScalingOp(discr, discr, 2) # Same weightings, no scaling in adjoint
op3 = ScalingOp(rn, discr, 2) # Different weightings, adjoint scales

# Look at output of ajoint
print('*** Ajoint evaluation ***')
print('Rn -> Rn adjoint at one :', op1.adjoint(op1.range.one()))
print('discr -> discr adjoint at one:', op2.adjoint(op2.range.one()))
print('Rn -> discr adjoint at one :', op3.adjoint(op3.range.one()))
print('')

# Check adjointness
print('*** Check adjointness ***')
inner1_dom = op1.domain.one().inner(op1.adjoint(op1.range.one()))
inner1_ran = op1(op1.domain.one()).inner(op1.range.one())
print('Rn -> Rn: <Sx, y> = {}, <x, S^*y> = {}'
''.format(inner1_ran, inner1_dom))

inner2_dom = op2.domain.one().inner(op2.adjoint(op2.range.one()))
inner2_ran = op2(op2.domain.one()).inner(op2.range.one())
print('discr -> discr: <Sx, y> = {}, <x, S^*y> = {}'
''.format(inner2_ran, inner2_dom))

inner3_dom = op3.domain.one().inner(op3.adjoint(op3.range.one()))
inner3_ran = op3(op3.domain.one()).inner(op3.range.one())
print('Rn -> discr: <Sx, y> = {}, <x, S^*y> = {}'
''.format(inner3_ran, inner3_dom))
2 changes: 1 addition & 1 deletion odl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
from . import solvers
from . import tomo
from . import trafos
from . import ufunc_ops
from . import oplib
from . import util

# Add `test` function to global namespace so users can run `odl.test()`
Expand Down
4 changes: 2 additions & 2 deletions odl/operator/tensor_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
from odl.space import ProductSpace, tensor_space
from odl.space.base_tensors import TensorSpace
from odl.space.weighting import ArrayWeighting
from odl.util import (
signature_string, indent, dtype_repr, moveaxis, writable_array)
from odl.util import signature_string, indent, dtype_repr, writable_array
from odl.util.npy_compat import moveaxis


__all__ = ('PointwiseNorm', 'PointwiseInner', 'PointwiseSum', 'MatrixOperator',
Expand Down
24 changes: 24 additions & 0 deletions odl/oplib/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2014-2017 The ODL contributors
#
# This file is part of ODL.
#
# This Source Code Form is subject to the terms of the Mozilla Public License,
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at https://mozilla.org/MPL/2.0/.

"""Library of operators.

This submodule is a place for operators that either do not fit in any other
places or require "advanced" features of ODL that would make them hard
to put into any other submodule due to circular dependencies.
"""

from __future__ import absolute_import

__all__ = ('convolution', 'ufunc_ops')

from .convolution import *
__all__ += convolution.__all__

from .ufunc_ops import *
__all__ += ufunc_ops.__all__
Loading