[pyoperators] 01/01: Imported Upstream version 0.13.10
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Sat Dec 19 12:51:36 UTC 2015
This is an automated email from the git hooks/post-receive script.
ghisvail-guest pushed a commit to branch upstream
in repository pyoperators.
commit 7079071f0bbd0b752639d9129071a5203ade32f9
Author: Ghislain Antony Vaillant <ghisvail at gmail.com>
Date: Sat Dec 19 12:29:39 2015 +0000
Imported Upstream version 0.13.10
---
PKG-INFO | 2 +-
hooks.py | 185 ++++++++++++++++++++++++++++++++++----
pyoperators/__init__.py | 15 ++--
pyoperators/core.py | 11 +--
pyoperators/fft.py | 14 ++-
pyoperators/iterative/optimize.py | 16 ++--
pyoperators/linear.py | 8 +-
pyoperators/nonlinear.py | 2 +-
pyoperators/operators_pywt.py | 46 ++++++----
pyoperators/rules.py | 18 ++--
pyoperators/utils/misc.py | 49 +++++-----
setup.py | 2 +-
test/test_broadcast.py | 180 +++++++++++++++++++++++++++++++++++++
test/test_zero.py | 4 +-
14 files changed, 454 insertions(+), 98 deletions(-)
diff --git a/PKG-INFO b/PKG-INFO
index fad8aed..4df0926 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: pyoperators
-Version: 0.13.6
+Version: 0.13.10
Summary: Operators and solvers for high-performance computing.
Home-page: http://pchanial.github.com/pyoperators
Author: Pierre Chanial
diff --git a/hooks.py b/hooks.py
index 8b23583..0fd1794 100644
--- a/hooks.py
+++ b/hooks.py
@@ -30,6 +30,20 @@ configurable) or the last tag.
# These variables can be changed by the hooks importer
ABBREV = 5
+F77_OPENMP = True
+F90_OPENMP = True
+F77_COMPILE_ARGS_GFORTRAN = []
+F77_COMPILE_DEBUG_GFORTRAN = ['-fcheck=all -Og']
+F77_COMPILE_OPT_GFORTRAN = ['-Ofast -march=native']
+F90_COMPILE_ARGS_GFORTRAN = ['-cpp']
+F90_COMPILE_DEBUG_GFORTRAN = ['-fcheck=all -Og']
+F90_COMPILE_OPT_GFORTRAN = ['-Ofast -march=native']
+F77_COMPILE_ARGS_IFORT = []
+F77_COMPILE_DEBUG_IFORT = ['-check all']
+F77_COMPILE_OPT_IFORT = ['-fast']
+F90_COMPILE_ARGS_IFORT = ['-fpp -ftz -fp-model precise -ftrapuv -warn all']
+F90_COMPILE_DEBUG_IFORT = ['-check all']
+F90_COMPILE_OPT_IFORT = ['-fast']
F2PY_TABLE = {'integer': {'int8': 'char',
'int16': 'short',
'int32': 'int',
@@ -38,6 +52,9 @@ F2PY_TABLE = {'integer': {'int8': 'char',
'real64': 'double'},
'complex': {'real32': 'complex_float',
'real64': 'complex_double'}}
+FCOMPILERS_DEFAULT = 'ifort', 'gfortran'
+LIBRARY_OPENMP_GFORTRAN = 'gomp'
+LIBRARY_OPENMP_IFORT = 'iomp5'
REGEX_RELEASE = '^v(?P<name>[0-9.]+)$'
try:
import os
@@ -52,10 +69,16 @@ import shutil
import sys
from distutils.command.clean import clean
from numpy.distutils.command.build import build
+from numpy.distutils.command.build_clib import build_clib
+from numpy.distutils.command.build_ext import build_ext
from numpy.distutils.command.build_src import build_src
from numpy.distutils.command.sdist import sdist
from numpy.distutils.core import Command
-from numpy.distutils.misc_util import has_f_sources
+from numpy.distutils.exec_command import find_executable
+from numpy.distutils.fcompiler import new_fcompiler
+from numpy.distutils.fcompiler.gnu import Gnu95FCompiler
+from numpy.distutils.fcompiler.intel import IntelEM64TFCompiler
+from numpy.distutils.misc_util import f90_ext_match, has_f_sources
from subprocess import call, Popen, PIPE
from warnings import filterwarnings
@@ -72,6 +95,24 @@ numpy.distutils.from_template.routine_start_re = re.compile(
numpy.distutils.from_template.function_start_re = re.compile(
r'\n (\$|\*)\s*((im)?pure\s+|elemental\s+)*function\b', re.I)
+# monkey patch compilers
+Gnu95FCompiler.get_flags_debug = lambda self: []
+Gnu95FCompiler.get_flags_opt = lambda self: []
+IntelEM64TFCompiler.get_flags_debug = lambda self: []
+IntelEM64TFCompiler.get_flags_opt = lambda self: []
+
+# monkey patch the default Fortran compiler
+if sys.platform.startswith('linux'):
+ _id = 'linux.*'
+elif sys.platform.startswith('darwin'):
+ _id = 'darwin.*'
+else:
+ _id = None
+if _id is not None:
+ table = {'ifort': 'intelem', 'gfortran': 'gnu95'}
+ _df = (_id, tuple(table[f] for f in FCOMPILERS_DEFAULT)),
+ numpy.distutils.fcompiler._default_compilers = _df
+
def get_cmdclass():
@@ -81,6 +122,114 @@ def get_cmdclass():
self.distribution.get_version())
build.run(self)
+ class BuildClibCommand(build_clib):
+ def build_libraries(self, libraries):
+ if numpy.__version__ < "1.7":
+ fcompiler = self.fcompiler
+ else:
+ fcompiler = self._f_compiler
+ if isinstance(fcompiler,
+ numpy.distutils.fcompiler.gnu.Gnu95FCompiler):
+ old_value = numpy.distutils.log.set_verbosity(-2)
+ exe = numpy.distutils.exec_command.find_executable('gcc-ar')
+ if exe is None:
+ exe = numpy.distutils.exec_command.find_executable('ar')
+ numpy.distutils.log.set_verbosity(old_value)
+ self.compiler.archiver[0] = exe
+ flags = F77_COMPILE_ARGS_GFORTRAN + F77_COMPILE_OPT_GFORTRAN
+ if self.debug:
+ flags += F77_COMPILE_DEBUG_GFORTRAN
+ if F77_OPENMP:
+ flags += ['-openmp']
+ fcompiler.executables['compiler_f77'] += flags
+ flags = F90_COMPILE_ARGS_GFORTRAN + F90_COMPILE_OPT_GFORTRAN
+ if self.debug:
+ flags += F90_COMPILE_DEBUG_GFORTRAN
+ if F90_OPENMP:
+ flags += ['-openmp']
+ fcompiler.executables['compiler_f90'] += flags
+ fcompiler.libraries += [LIBRARY_OPENMP_GFORTRAN]
+ elif isinstance(fcompiler,
+ numpy.distutils.fcompiler.intel.IntelFCompiler):
+ old_value = numpy.distutils.log.set_verbosity(-2)
+ self.compiler.archiver[0] = numpy.distutils.exec_command.find_executable('xiar')
+ numpy.distutils.log.set_verbosity(old_value)
+ flags = F77_COMPILE_ARGS_IFORT + F77_COMPILE_OPT_IFORT
+ if self.debug:
+ flags += F77_COMPILE_DEBUG_IFORT
+ if F77_OPENMP:
+ flags += ['-openmp']
+ fcompiler.executables['compiler_f77'] += flags
+ flags = F90_COMPILE_ARGS_IFORT + F90_COMPILE_OPT_IFORT
+ if self.debug:
+ flags += F90_COMPILE_DEBUG_IFORT
+ if F90_OPENMP:
+ flags += ['-openmp']
+ fcompiler.executables['compiler_f90'] += flags
+ fcompiler.libraries += [LIBRARY_OPENMP_IFORT]
+ else:
+ raise RuntimeError()
+ build_clib.build_libraries(self, libraries)
+
+ class BuildExtCommand(build_ext):
+ def build_extensions(self):
+ # Numpy bug: if an extension has a library only consisting of f77
+ # files, the extension language will always be f77 and no f90
+ # compiler will be initialized
+ need_f90_compiler = self._f90_compiler is None and \
+ any(any(f90_ext_match(s) for s in _.sources)
+ for _ in self.extensions)
+ if need_f90_compiler:
+ self._f90_compiler = new_fcompiler(compiler=self.fcompiler,
+ verbose=self.verbose,
+ dry_run=self.dry_run,
+ force=self.force,
+ requiref90=True,
+ c_compiler=self.compiler)
+ fcompiler = self._f90_compiler
+ if fcompiler:
+ fcompiler.customize(self.distribution)
+ if fcompiler and fcompiler.get_version():
+ fcompiler.customize_cmd(self)
+ fcompiler.show_customization()
+ else:
+ ctype = fcompiler.compiler_type if fcompiler \
+ else self.fcompiler
+ self.warn('f90_compiler=%s is not available.' % ctype)
+
+ for fc in self._f77_compiler, self._f90_compiler:
+ if isinstance(fc,
+ numpy.distutils.fcompiler.gnu.Gnu95FCompiler):
+ flags = F77_COMPILE_ARGS_GFORTRAN + F77_COMPILE_OPT_GFORTRAN
+ if self.debug:
+ flags += F77_COMPILE_DEBUG_GFORTRAN
+ if F77_OPENMP:
+ flags += ['-openmp']
+ fc.executables['compiler_f77'] += flags
+ flags = F90_COMPILE_ARGS_GFORTRAN + F90_COMPILE_OPT_GFORTRAN
+ if self.debug:
+ flags += F90_COMPILE_DEBUG_GFORTRAN
+ if F90_OPENMP:
+ flags += ['-openmp']
+ fc.executables['compiler_f90'] += flags
+ fc.libraries += [LIBRARY_OPENMP_GFORTRAN]
+ elif isinstance(fc,
+ numpy.distutils.fcompiler.intel.IntelFCompiler):
+ flags = F77_COMPILE_ARGS_IFORT + F77_COMPILE_OPT_IFORT
+ if self.debug:
+ flags += F77_COMPILE_DEBUG_IFORT
+ if F77_OPENMP:
+ flags += ['-openmp']
+ fc.executables['compiler_f77'] += flags
+ flags = F90_COMPILE_ARGS_IFORT + F90_COMPILE_OPT_IFORT
+ if self.debug:
+ flags += F90_COMPILE_DEBUG_IFORT
+ if F90_OPENMP:
+ flags += ['-openmp']
+ fc.executables['compiler_f90'] += flags
+ fc.libraries += [LIBRARY_OPENMP_IFORT]
+ build_ext.build_extensions(self)
+
class BuildSrcCommand(build_src):
def initialize_options(self):
build_src.initialize_options(self)
@@ -126,11 +275,9 @@ def get_cmdclass():
class CleanCommand(clean):
def run(self):
clean.run(self)
- try:
+ if is_git_tree():
print(run_git('clean -fdX' + ('n' if self.dry_run else '')))
return
- except RuntimeError:
- pass
extensions = '.o', '.pyc', 'pyd', 'pyo', '.so'
for root_, dirs, files in os.walk(root):
@@ -140,12 +287,6 @@ def get_cmdclass():
for d in dirs:
if d in ('build', '__pycache__'):
self.__delete(os.path.join(root_, d), dir=True)
- files = (
- 'MANIFEST',
- os.path.join(self.distribution.get_name(), '__init__.py'))
- for f in files:
- if os.path.exists(f):
- self.__delete(f)
def __delete(self, file_, dir=False):
msg = 'would remove' if self.dry_run else 'removing'
@@ -197,6 +338,8 @@ def get_cmdclass():
pass
return {'build': BuildCommand,
+ 'build_clib': BuildClibCommand,
+ 'build_ext': BuildExtCommand,
'build_src': BuildSrcCommand,
'clean': CleanCommand,
'coverage': CoverageCommand,
@@ -219,11 +362,15 @@ def run_git(cmd, cwd=root):
if stderr != '':
stderr = '\n' + stderr.decode('utf-8')
raise RuntimeError(
- 'Command failed (error {}): {}{}'.format(
+ 'Command failed (error {0}): {1}{2}'.format(
process.returncode, cmd, stderr))
return stdout.strip().decode('utf-8')
+def is_git_tree():
+ return os.path.exists(os.path.join(root, '.git'))
+
+
def _get_version_git(default):
INF = 2147483647
@@ -241,10 +388,11 @@ def _get_version_git(default):
def get_description():
branch = get_branch_name()
try:
- description = run_git('describe --abbrev={} --tags'.format(ABBREV))
+ description = run_git(
+ 'describe --abbrev={0} --tags'.format(ABBREV))
except RuntimeError:
description = run_git(
- 'describe --abbrev={} --always'.format(ABBREV))
+ 'describe --abbrev={0} --always'.format(ABBREV))
regex = r"""^
(?P<commit>.*?)
(?P<dirty>(-dirty)?)
@@ -277,7 +425,8 @@ def _get_version_git(default):
common = run_git('merge-base HEAD ' + branch)
except RuntimeError:
return INF # no common ancestor, the branch is dangling
- return int(run_git('rev-list --count HEAD ^' + common))
+ # git 1.8: return int(run_git('rev-list --count HEAD ^' + common))
+ return len(run_git('rev-list HEAD ^' + common).split('\n'))
def get_rev_since_any_branch():
if REGEX_RELEASE.startswith('^'):
@@ -297,9 +446,7 @@ def _get_version_git(default):
# no branch has been created from an ancestor
return INF
- try:
- run_git('rev-parse --is-inside-work-tree')
- except (OSError, RuntimeError):
+ if not is_git_tree():
return ''
branch, tag, rev_tag, commit, dirty = get_description()
@@ -331,7 +478,7 @@ def _get_version_git(default):
if rev_branch == rev_tag == INF:
# no branch and no tag from ancestors, counting from root
- rev = int(run_git('rev-list --count HEAD'))
+ rev = len(run_git('rev-list HEAD').split('\n'))
if branch != 'master':
suffix = 'rev'
elif rev_tag <= rev_branch:
@@ -346,7 +493,7 @@ def _get_version_git(default):
suffix = 'pre'
if name != '':
name += '.'
- return '{}{}{:02}{}'.format(name, suffix, rev, dirty)
+ return '{0}{1}{2:02}{3}'.format(name, suffix, rev, dirty)
def _get_version_init_file(name):
diff --git a/pyoperators/__init__.py b/pyoperators/__init__.py
index f74350b..bf886a4 100644
--- a/pyoperators/__init__.py
+++ b/pyoperators/__init__.py
@@ -10,7 +10,6 @@ The PyOperators package contains the following modules or packages:
- operators_pywt : (optional) loaded if PyWavelets is present.
"""
-
from .utils import *
from .utils.mpi import MPI
from .core import *
@@ -18,19 +17,19 @@ from .fft import *
from .linear import *
from .nonlinear import *
from .operators_mpi import *
+try:
+ import pywt
+ from .operators_pywt import *
+except ImportError:
+ pass
from .proxy import *
from . import iterative
from .iterative import pcg
from .rules import rule_manager
from .warnings import PyOperatorsWarning
-
-try:
- from .operators_pywt import *
-except(ImportError):
- pass
-
import sys
import types
+
__all__ = [f for f in dir() if f[0] != '_' and not isinstance(eval(f),
types.ModuleType)]
@@ -43,4 +42,4 @@ I = IdentityOperator()
O = ZeroOperator()
X = Variable('X')
-__version__ = u'0.13.6'
+__version__ = u'0.13.10'
diff --git a/pyoperators/core.py b/pyoperators/core.py
index 4525704..e168526 100644
--- a/pyoperators/core.py
+++ b/pyoperators/core.py
@@ -100,7 +100,7 @@ class Operator(object):
and input dtypes. If dtype is None, the output dtype is the input
dtype.
C : Operator
- Oonjugate operator.
+ Conjugate operator.
T : Operator
Tranpose operator.
H : Operator
@@ -1528,7 +1528,7 @@ class CompositeOperator(Operator):
def _validate_operands(self, operands, constant=False):
if not isinstance(operands, (list, tuple, types.GeneratorType)):
- operands = [operands]
+ raise TypeError('The expected input is a sequence of operators.')
return [asoperator(op, constant=constant) for op in operands]
def _validate_comm(self, operands):
@@ -1835,7 +1835,7 @@ class BlockSliceOperator(CommutativeCompositeOperator):
Examples
--------
- >>> op = BlockSliceOperator(HomothetyOperator(3), slice(None,None,2))
+ >>> op = BlockSliceOperator([HomothetyOperator(3)], slice(None,None,2))
>>> op(np.ones(6))
array([ 3., 1., 3., 1., 3., 1.])
@@ -3335,7 +3335,8 @@ class BlockRowOperator(BlockOperator):
keywords.get('flags', {}), linear=operation is operator.iadd)
BlockOperator.__init__(self, operands, partitionin=partitionin, axisin=
axisin, new_axisin=new_axisin, **keywords)
-
+ if not isinstance(self, BlockRowOperator):
+ return
self.operation = operation
self._need_temporary = any(not o.flags.update_output for o in
self.operands[1:])
@@ -3532,7 +3533,7 @@ class BroadcastingBase(Operator):
return
else:
if b == 'rightward':
- if axis_ >= ndim:
+ if axis_ > ndim:
do_replicate = True
else:
if axis is not None:
diff --git a/pyoperators/fft.py b/pyoperators/fft.py
index a22a647..358d53e 100644
--- a/pyoperators/fft.py
+++ b/pyoperators/fft.py
@@ -15,8 +15,6 @@ from .utils import (complex_dtype, isalias, omp_num_threads, product,
from .utils.ufuncs import multiply_conjugate
from .warnings import warn, PyOperatorsWarning
-__all__ = ['ConvolutionOperator', 'FFTOperator']
-
try:
import pyfftw
FFTW_DEFAULT_NUM_THREADS = omp_num_threads()
@@ -27,6 +25,18 @@ try:
except:
warn('The pyFFTW library is not installed.', PyOperatorsWarning)
+__all__ = ['ConvolutionOperator', 'FFTOperator']
+
+
+# doctest nose fixture
+def setup_module(module):
+ try:
+ import pyfftw
+ except ImportError:
+ from nose.plugins.skip import SkipTest
+ raise SkipTest()
+
+
# FFTW out-of-place transforms:
# PRESERVE_INPUT: default except c2r and hc2r
# DESTROY_INPUT: default for c2r and hc2r, only possibility for multi c2r
diff --git a/pyoperators/iterative/optimize.py b/pyoperators/iterative/optimize.py
index 51fae5a..02c36a9 100644
--- a/pyoperators/iterative/optimize.py
+++ b/pyoperators/iterative/optimize.py
@@ -60,7 +60,7 @@ class FminWrapper(object):
class FminCOBYLA(FminWrapper):
- __doc__ = FminWrapper.__doc__ + opt.fmin_cobyla.__doc__
+# __doc__ = FminWrapper.__doc__ + opt.fmin_cobyla.__doc__
def __init__(self, criterion, cons, x0=None, *args, **kwargs):
self.cons = cons
@@ -82,7 +82,7 @@ class FminCOBYLA(FminWrapper):
class FminPowell(FminWrapper):
- __doc__ = FminWrapper.__doc__ + opt.fmin_powell.__doc__
+# __doc__ = FminWrapper.__doc__ + opt.fmin_powell.__doc__
def __call__(self):
self.first_guess()
@@ -99,7 +99,7 @@ class FminPowell(FminWrapper):
class FminCG(FminWrapper):
- __doc__ = FminWrapper.__doc__ + opt.fmin_cg.__doc__
+# __doc__ = FminWrapper.__doc__ + opt.fmin_cg.__doc__
def __call__(self):
self.first_guess()
@@ -117,7 +117,7 @@ class FminCG(FminWrapper):
class FminTNC(FminWrapper):
- __doc__ = FminWrapper.__doc__ + opt.fmin_tnc.__doc__
+# __doc__ = FminWrapper.__doc__ + opt.fmin_tnc.__doc__
def __call__(self):
self.first_guess()
@@ -135,7 +135,7 @@ class FminTNC(FminWrapper):
class FminNCG(FminWrapper):
- __doc__ = FminWrapper.__doc__ + opt.fmin_ncg.__doc__
+# __doc__ = FminWrapper.__doc__ + opt.fmin_ncg.__doc__
def __init__(self, criterion, x0=None, *args, **kwargs):
super(FminNCG, self).__init__(criterion, x0=x0, *args, **kwargs)
@@ -160,7 +160,7 @@ class FminNCG(FminWrapper):
class FminLBFGSB(FminWrapper):
- __doc__ = FminWrapper.__doc__ + opt.fmin_l_bfgs_b.__doc__
+# __doc__ = FminWrapper.__doc__ + opt.fmin_l_bfgs_b.__doc__
def __call__(self):
self.first_guess()
@@ -178,7 +178,7 @@ class FminLBFGSB(FminWrapper):
class FminSLSQP(FminWrapper):
- __doc__ = FminWrapper.__doc__ + opt.fmin_slsqp.__doc__
+# __doc__ = FminWrapper.__doc__ + opt.fmin_slsqp.__doc__
def __call__(self):
self.first_guess()
@@ -197,7 +197,7 @@ class FminSLSQP(FminWrapper):
class FminBFGS(FminWrapper):
- __doc__ = FminWrapper.__doc__ + opt.fmin_bfgs.__doc__
+# __doc__ = FminWrapper.__doc__ + opt.fmin_bfgs.__doc__
def __call__(self):
self.first_guess()
diff --git a/pyoperators/linear.py b/pyoperators/linear.py
index cf57824..9e6e9af 100644
--- a/pyoperators/linear.py
+++ b/pyoperators/linear.py
@@ -754,7 +754,6 @@ class Rotation2dOperator(DenseBlockDiagonalOperator):
Example
-------
>>> r = Rotation2dOperator([45, 90], degrees=True)
- >>> r([1, 0])
>>> print(r([1, 0]))
[[ 7.07106781e-01 7.07106781e-01]
[ 6.12323400e-17 1.00000000e+00]]
@@ -821,7 +820,7 @@ class Rotation3dOperator(DenseBlockDiagonalOperator):
[ 6.12323400e-17 0.00000000e+00 -1.00000000e+00]
>>> r2 = Rotation3dOperator("XYZ", 30, 40, 50, degrees=True)
>>> print(r2([1, 0, 0]))
- [ 0.49240388 0.58682409 -0.64278761]d
+ [ 0.49240388 0.58682409 -0.64278761]
>>> r3 = Rotation3dOperator("ZY'X''", 50, 40, 30, degrees=True)
>>> print(r3([1, 0, 0]))
[ 0.49240388 0.58682409 -0.64278761]
@@ -1046,9 +1045,8 @@ class TridiagonalOperator(Operator):
Exemple
-------
- >>> import operators
- >>> T = operators.TridiagonalOperator([1, 2, 3], [4, 5], [6, 7])
- >>> T.todense()
+ >>> tri = TridiagonalOperator([1, 2, 3], [4, 5], [6, 7])
+ >>> tri.todense()
array([[1, 6, 0],
[4, 2, 7],
[0, 5, 3]])
diff --git a/pyoperators/nonlinear.py b/pyoperators/nonlinear.py
index a695c57..9ab36bd 100644
--- a/pyoperators/nonlinear.py
+++ b/pyoperators/nonlinear.py
@@ -617,7 +617,7 @@ class NumexprOperator(Operator):
-------
>>> k = 1.2
>>> op = NumexprOperator('exp(input+k)', {'k':k})
- >>> print op(1) == np.exp(2.2)
+ >>> print(op(1) == np.exp(2.2))
True
"""
diff --git a/pyoperators/operators_pywt.py b/pyoperators/operators_pywt.py
index a33b960..d00458d 100644
--- a/pyoperators/operators_pywt.py
+++ b/pyoperators/operators_pywt.py
@@ -4,29 +4,41 @@ For now only 1D and 2D wavelets are available.
"""
from __future__ import absolute_import, division, print_function
-import numpy as np
-import pywt
from .core import Operator, CompositionOperator
from .flags import linear, real
+import numpy as np
+try:
+ import pywt
+ # dict of corresponding wavelets
+ rwavelist = {}
+ for l in pywt.wavelist():
+ if 'bior' in l:
+ rwavelist[l] = 'rbio' + l[-3:]
+ elif 'rbio' in l:
+ rwavelist[l] = 'bior' + l[-3:]
+ else:
+ rwavelist[l] = l
+except ImportError:
+ pass
__all__ = ['WaveletOperator', 'Wavelet2dOperator']
-# dict of corresponding wavelets
-rwavelist = {}
-for l in pywt.wavelist():
- if 'bior' in l:
- rwavelist[l] = 'rbio' + l[-3:]
- elif 'rbio' in l:
- rwavelist[l] = 'bior' + l[-3:]
- else:
- rwavelist[l] = l
+
+# doctest nose fixture
+def setup_module(module):
+ try:
+ import pywt
+ except ImportError:
+ from nose.plugins.skip import SkipTest
+ raise SkipTest()
@real
@linear
class WaveletOperator(Operator):
+ skip_doctest = True
def __init__(self, wavelet, mode='zpd', level=None, shapein=None,
- **keywords):
+ dtype=float, **keywords):
"""
1D wavelet decomposition and reconstruction. Wavelet coefficients
are stored in a vector (ndarray with ndim=1).
@@ -35,7 +47,6 @@ class WaveletOperator(Operator):
--------
>>> W = WaveletOperator("haar", level=1, shapein=2)
>>> W.todense()
-
array([[ 0.70710678, 0.70710678],
[ 0.70710678, -0.70710678]])
@@ -63,7 +74,8 @@ class WaveletOperator(Operator):
self.cumsizes = np.zeros(len(self.sizes) + 1)
np.cumsum(self.sizes, out=self.cumsizes[1:])
shapeout = sum(self.sizes)
- Operator.__init__(self, shapein=shapein, shapeout=shapeout, **keywords)
+ Operator.__init__(self, shapein=shapein, shapeout=shapeout,
+ dtype=dtype, **keywords)
if self.wavelet.orthogonal:
self.set_rule('T,.', '1', CompositionOperator)
@@ -89,7 +101,7 @@ class WaveletOperator(Operator):
@linear
class Wavelet2dOperator(Operator):
def __init__(self, wavelet, mode='zpd', level=None, shapein=None,
- **keywords):
+ dtype=float, **keywords):
"""
2D wavelet decomposition and reconstruction. Wavelet coefficients
are stored in a vector (ndarray with ndim=1).
@@ -98,7 +110,6 @@ class Wavelet2dOperator(Operator):
-------
>>> W = Wavelet2dOperator("haar", level=1, shapein=(2, 2))
>>> W.todense()
-
array([[ 0.5, 0.5, 0.5, 0.5],
[ 0.5, 0.5, -0.5, -0.5],
[ 0.5, -0.5, 0.5, -0.5],
@@ -133,7 +144,8 @@ class Wavelet2dOperator(Operator):
np.cumsum(self.sizes, out=self.cumsizes[1:])
shapeout = sum(self.sizes)
- Operator.__init__(self, shapein=shapein, shapeout=shapeout, **keywords)
+ Operator.__init__(self, shapein=shapein, shapeout=shapeout,
+ dtype=dtype, **keywords)
if self.wavelet.orthogonal:
self.set_rule('T,.', '1', CompositionOperator)
diff --git a/pyoperators/rules.py b/pyoperators/rules.py
index 703e4ae..7fb007a 100644
--- a/pyoperators/rules.py
+++ b/pyoperators/rules.py
@@ -265,28 +265,32 @@ class RuleManager(object):
Examples
--------
To prevent rule simplifications:
- >>> from pyoperators.rules import rules
- >>> rules['none'] = True
+ >>> from pyoperators.rules import rule_manager
+ >>> rule_manager['none'] = True
+
+ To re-enable rule simplifications:
+ >>> rule_manager['none'] = False
+
or:
- >>> with rules(none=True):
- ... print(rules['none'])
+ >>> with rule_manager(none=True):
... # in this context, operator simplification rules are inhibited
- >>> print(rules['none'])
+ ... print(rule_manager['none'])
True
+ >>> print(rule_manager['none'])
False
It is possible to nest contexts:
>>> print(rule_manager['none'])
+ False
>>> with rule_manager(none=True) as new_rule_manager:
... print(rule_manager['none'])
... with new_rule_manager(none=False):
... print(rule_manager['none'])
... print(rule_manager['none'])
- >>> print(rule_manager['none'])
- False
True
False
True
+ >>> print(rule_manager['none'])
False
"""
diff --git a/pyoperators/utils/misc.py b/pyoperators/utils/misc.py
index 1bfaee1..30c3c1e 100644
--- a/pyoperators/utils/misc.py
+++ b/pyoperators/utils/misc.py
@@ -85,12 +85,15 @@ def deprecated(msg):
Example
-------
>>> @deprecated('use mynewfunc instead.')
- >>> def myfunc():
+ ... def myfunc():
... pass
- >>>@deprecated
- >>>class MyClass(MyNewClass):
- >>> pass
+ >>> class MyNewClass(object):
+ ... # here goes the new class to be used instead of the deprecated one
+ ... pass
+ >>> @deprecated
+ ... class MyClass(MyNewClass):
+ ... pass
"""
def decorator(x):
@@ -572,9 +575,9 @@ def inspect_special_values(x):
Examples
--------
>>> inspect_special_values([0,-1,-1])
- 2, 1, 0, False, False
+ (2, 1, 0, False, False)
>>> inspect_special_values([0,-1,-1,1.2])
- 0, 0, 0, True, False
+ (0, 0, 0, True, False)
"""
x = np.asarray(x)
@@ -655,7 +658,7 @@ def last(l, f):
Example:
--------
- >>> first([1.,2.,3.], lambda x: x > 1.5)
+ >>> last([1.,2.,3.], lambda x: x > 1.5)
3.0
"""
@@ -731,7 +734,7 @@ def merge_none(a, b):
Example
-------
>>> merge_none([1,None,3],[None,2,3])
- [1, 2, 3]
+ (1, 2, 3)
"""
if a is b is None:
return None
@@ -851,7 +854,7 @@ def reshape_broadcast(x, shape):
[[[0 0]
[1 1]
[2 2]]
-
+ <BLANKLINE>
[[0 0]
[1 1]
[2 2]]]
@@ -946,8 +949,8 @@ def strelapsed(t0, msg='Elapsed time'):
>>> import time
>>> t0 = time.time()
>>> pass
- >>> print(strelapsed(t0, 'Did nothing in'))
- Info computernode: Did nothing in... 0.00s
+ >>> strelapsed(t0, 'Did nothing in') # doctest: +ELLIPSIS
+ 'Info ...: Did nothing in... 0.00s'
"""
import time
@@ -989,8 +992,8 @@ def strinfo(msg):
The information message.
Example
-------
- >>> print(strinfo('My information message'))
- Info computernode: My information message.
+ >>> strinfo('My information message') # doctest: +ELLIPSIS
+ 'Info ...: My information message.'
"""
from .mpi import MPI
@@ -1016,8 +1019,8 @@ def strnbytes(nbytes):
Example
-------
>>> a = np.empty((100,100))
- >>> print(strnbytes(a.nbytes))
- 78.125 KiB
+ >>> strnbytes(a.nbytes)
+ '78.125 KiB'
"""
if nbytes < 1024:
@@ -1053,7 +1056,7 @@ def strplural(n, name, nonumber=False, s=''):
'1 cat'
>>> strplural(2, 'cat')
'2 cats'
- >>> strplural(2, 'cat', prepend=False)
+ >>> strplural(2, 'cat', nonumber=True)
'cats'
>>> animals = ['cat', 'dog']
>>> strplural(len(animals), 'animal', s=': ') + ', '.join(animals)
@@ -1096,26 +1099,26 @@ class Timer(object):
Examples
--------
>>> import time
- >>> with Timer('Elapsed time: '):
+ >>> with Timer('Elapsed time: '): # doctest: +SKIP
... time.sleep(0.1)
Elapsed time: 0.100191831589s
- >>> with Timer() as t:
+ >>> with Timer() as t: # doctest: +SKIP
... time.sleep(0.1)
... print(t.elapsed)
... time.sleep(0.1)
- ... print(t.elapsed)
0.100234985352
+ >>> print(t.elapsed) # doctest: +SKIP
0.200633049011
>>> t = Timer(cumulative=True)
>>> with t:
... time.sleep(0.1)
- >>> print(t.elapsed)
- >>> with t:
- ... time.sleep(0.1)
- >>> print(t.elapsed)
+ >>> print(t.elapsed) # doctest: +SKIP
0.100238084793
+ >>> with t:
+ ... time.sleep(0.1) # doctest: +SKIP
+ >>> print(t.elapsed) # doctest: +SKIP
0.200490236282
"""
diff --git a/setup.py b/setup.py
index 5b60b0a..6367a2e 100644
--- a/setup.py
+++ b/setup.py
@@ -11,7 +11,7 @@ name = 'pyoperators'
long_description = open('README.rst').read()
keywords = 'scientific computing'
platforms = 'MacOS X,Linux,Solaris,Unix,Windows'
-define_macros = [] if sys.version_info.major == 2 else [('NPY_PY3K', None)]
+define_macros = [] if sys.version_info[0] == 2 else [('NPY_PY3K', None)]
ext_modules = [Extension("pyoperators.utils.cythonutils",
sources=["pyoperators/utils/cythonutils.pyx"],
diff --git a/test/test_broadcast.py b/test/test_broadcast.py
new file mode 100644
index 0000000..427f91e
--- /dev/null
+++ b/test/test_broadcast.py
@@ -0,0 +1,180 @@
+from numpy.testing import assert_equal
+from pyoperators import Operator, operation_assignment
+from pyoperators.core import _pool
+from pyoperators.utils.testing import assert_same
+from pyoperators.flags import handle_broadcast
+import numpy as np
+
+
+data = np.array([[0, 1], [1, 2], [2, 3]])
+m = data.shape[0]
+n = data.shape[1]
+
+
+class MyOperator(Operator):
+ def direct(self, input, output):
+ np.dot(data, input, out=output)
+
+
+class ExplExpl(MyOperator):
+ def __init__(self, **keywords):
+ MyOperator.__init__(self, shapein=n, shapeout=m, **keywords)
+
+
+ at handle_broadcast('leftward')
+class ExplExplLeft(ExplExpl):
+ pass
+
+
+ at handle_broadcast('rightward')
+class ExplExplRight(ExplExpl):
+ def direct(self, input, output):
+ np.dot(data, input.T, out=output.T)
+
+
+class ExplUnco(MyOperator):
+ def __init__(self, **keywords):
+ MyOperator.__init__(self, shapeout=m, naxesin=1, **keywords)
+
+
+ at handle_broadcast('leftward')
+class ExplUncoLeft(ExplUnco):
+ pass
+
+
+ at handle_broadcast('rightward')
+class ExplUncoRight(ExplUnco):
+ def direct(self, input, output):
+ np.dot(data, input.T, out=output.T)
+
+
+class UncoExpl(MyOperator):
+ def __init__(self, **keywords):
+ MyOperator.__init__(self, shapein=n, naxesout=1, **keywords)
+
+
+ at handle_broadcast('leftward')
+class UncoExplLeft(UncoExpl):
+ pass
+
+
+ at handle_broadcast('rightward')
+class UncoExplRight(UncoExpl):
+ def direct(self, input, output):
+ np.dot(data, input.T, out=output.T)
+
+
+class ImplImpl(MyOperator):
+ def __init__(self, **keywords):
+ MyOperator.__init__(self, naxesin=1, naxesout=1, **keywords)
+
+ def reshapein(self, shape):
+ return (m,)
+
+ def reshapeout(self, shape):
+ return (n,)
+
+
+ at handle_broadcast('leftward')
+class ImplImplLeft(ImplImpl):
+ pass
+
+
+ at handle_broadcast('rightward')
+class ImplImplRight(ImplImpl):
+ def direct(self, input, output):
+ np.dot(data, input.T, out=output.T)
+
+
+class ImplUnco(MyOperator):
+ def __init__(self, **keywords):
+ MyOperator.__init__(self, naxesin=1, naxesout=1, **keywords)
+
+ def reshapein(self, shape):
+ return (m,)
+
+
+ at handle_broadcast('leftward')
+class ImplUncoLeft(ImplUnco):
+ pass
+
+
+ at handle_broadcast('rightward')
+class ImplUncoRight(ImplUnco):
+ def direct(self, input, output):
+ np.dot(data, input.T, out=output.T)
+
+
+class UncoImpl(MyOperator):
+ def __init__(self, **keywords):
+ MyOperator.__init__(self, naxesin=1, naxesout=1, **keywords)
+
+ def reshapeout(self, shape):
+ return (n,)
+
+
+ at handle_broadcast('leftward')
+class UncoImplLeft(UncoImpl):
+ pass
+
+
+ at handle_broadcast('rightward')
+class UncoImplRight(UncoImpl):
+ def direct(self, input, output):
+ np.dot(data, input.T, out=output.T)
+
+
+def repeat_iter(iterable, n=1):
+ for _ in iterable:
+ for i in xrange(n):
+ yield _
+
+
+cls = (ExplExpl, ExplExplLeft, ExplExplRight,
+ ExplUnco, ExplUncoLeft, ExplUncoRight,
+ UncoExpl, UncoExplLeft, UncoExplRight,
+ ImplImpl, ImplImplLeft, ImplImplRight,
+ ImplUnco, ImplUncoLeft, ImplUncoRight,
+ UncoImpl, UncoImplLeft, UncoImplRight)
+
+
+def test_nobroadcast():
+ def func(cls, k, b):
+ op = cls(broadcast=b)
+ assert_equal(cls.__name__[:8].lower(),
+ op.flags.shape_output[:4] + op.flags.shape_input[:4])
+ assert_same(op.todense(**k), data)
+ keywords = repeat_iter(({},
+ {'shapein': n},
+ {'shapeout': m},
+ {'shapein': n},
+ {'shapein': n},
+ {'shapeout': m}), n=3)
+ for cls_, keywords_ in zip(cls, keywords):
+ for b in 'leftward', 'rightward':
+ yield func, cls_, keywords_, b
+
+
+def test_broadcast():
+ def p(s, k):
+ if broadcast == 'leftward':
+ return s + (k,)
+ return (k,) + s
+
+ def func(bshape, broadcast, cls, keywords):
+ op = cls(broadcast=broadcast)
+ if broadcast == 'leftward':
+ dense = np.kron(np.eye(np.product(bshape)), data)
+ else:
+ dense = np.kron(data, np.eye(np.product(bshape)))
+ assert_same(op.todense(**keywords), dense)
+ for bshape in (1,), (2,), (2, 1), (1, 2), (2, 3):
+ for broadcast in 'leftward', 'rightward':
+ keywords = repeat_iter(({'shapein': p(bshape, n)},
+ {'shapein': p(bshape, n)},
+ {'shapeout': p(bshape, m)},
+ {'shapein': p(bshape, n)},
+ {'shapein': p(bshape, n)},
+ {'shapeout': p(bshape, m)}), n=3)
+ for cls_, keywords_ in zip(cls, keywords):
+ yield func, bshape, broadcast, cls_, keywords_
diff --git a/test/test_zero.py b/test/test_zero.py
index ef40842..877b8bf 100644
--- a/test/test_zero.py
+++ b/test/test_zero.py
@@ -6,7 +6,8 @@ from pyoperators import (
rule_manager, O)
from pyoperators.utils import ndarraywrap
from pyoperators.utils.testing import (
- assert_is, assert_is_instance, assert_is_none, assert_same, assert_is_type)
+ assert_is, assert_is_instance, assert_is_none, assert_same, assert_is_type,
+ skiptest)
from .common import OPS, ndarray2, attr2
op = Operator()
@@ -68,6 +69,7 @@ def test_zero5():
assert_equal(oz.shapeout, o.shapeout, 'oz, out')
+ at skiptest
def test_zero6():
@flags.linear
class Op(Operator):
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/pyoperators.git
More information about the debian-science-commits
mailing list