def assemble(self, mu=None): if hasattr(self, '_assembled_operator'): if self._defaults_sid == defaults_sid(): return self._assembled_operator else: self.logger.warn( 'Re-assembling since state of global defaults has changed.' ) operators = [op.assemble(mu) for op in self.operators] coefficients = self.evaluate_coefficients(mu) op = operators[0].assemble_lincomb(operators, coefficients, name=self.name + '_assembled') if not self.parametric: if op: self._assembled_operator = op self._defaults_sid = defaults_sid() return op else: self._try_assemble = False return self elif op: return op else: return LincombOperator(operators, coefficients, name=self.name + '_assembled')
def assemble(self, mu=None): """Assembles the operator for a given |Parameter|. Parameters ---------- mu The |Parameter| for which to assemble the operator. Returns ------- The assembled **parameter independent** |Operator|. """ if hasattr(self, '_assembled_operator'): if self._defaults_sid != defaults_sid(): self.logger.warn('Re-assembling since state of global defaults has changed.') op = self._assembled_operator = NumpyMatrixOperator(self._assemble(), solver_options=self.solver_options) self._defaults_sid = defaults_sid() return op else: return self._assembled_operator elif not self.parameter_type: op = self._assembled_operator = NumpyMatrixOperator(self._assemble(), solver_options=self.solver_options) self._defaults_sid = defaults_sid() return op else: return NumpyMatrixOperator(self._assemble(self.parse_parameter(mu)), solver_options=self.solver_options)
def assemble(self, mu=None): if hasattr(self, '_assembled_operator'): if self._defaults_sid == defaults_sid(): return self._assembled_operator else: self.logger.warn( 'Re-assembling since state of global defaults has changed.' ) operators = [op.assemble(mu) for op in self.operators] coefficients = self.evaluate_coefficients(mu) op = operators[0].assemble_lincomb( operators, coefficients, solver_options=self.solver_options, name=self.name + '_assembled') if not self.parametric: if op: self._assembled_operator = op self._defaults_sid = defaults_sid() return op else: self._try_assemble = False return self elif op: return op else: return LincombOperator( operators, coefficients, solver_options=self.solver_options, name=self.name + '_assembled')
def assemble(self, mu=None): """Assembles the operator for a given |Parameter|. Parameters ---------- mu The |Parameter| for which to assemble the operator. Returns ------- The assembled **parameter independent** |Operator|. """ if hasattr(self, '_assembled_operator'): if self._defaults_sid != defaults_sid(): self.logger.warn( 'Re-assembling since state of global defaults has changed.' ) op = self._assembled_operator = NumpyMatrixOperator( self._assemble()) self._defaults_sid = defaults_sid() return op else: return self._assembled_operator elif self.parameter_type is None: op = self._assembled_operator = NumpyMatrixOperator( self._assemble()) self._defaults_sid = defaults_sid() return op else: return NumpyMatrixOperator(self._assemble( self.parse_parameter(mu)))
def pairwise_apply2(self, V, U, U_ind=None, V_ind=None, mu=None, product=None): if hasattr(self, '_assembled_operator'): if self._defaults_sid == defaults_sid(): return self._assembled_operator.pairwise_apply2( V, U, V_ind=V_ind, U_ind=U_ind, product=product) else: return self.assemble().pairwise_apply2( V, U, V_ind=V_ind, U_ind=U_ind, product=product) elif self._try_assemble: return self.assemble().pairwise_apply2( V, U, V_ind=V_ind, U_ind=U_ind, product=product) coeffs = self.evaluate_coefficients(mu) R = self.operators[0].pairwise_apply2( V, U, V_ind=V_ind, U_ind=U_ind, mu=mu, product=product) R *= coeffs[0] for op, c in izip(self.operators[1:], coeffs[1:]): R += c * op.pairwise_apply2( V, U, V_ind=V_ind, U_ind=U_ind, mu=mu, product=product) return R
def _cached_method_call(self, method, pass_self, argnames, defaults, args, kwargs): if not cache_regions: default_regions() try: region = cache_regions[self.cache_region] except KeyError: raise KeyError(f'No cache region "{self.cache_region}" found') # compute id for self if region.persistent: self_id = getattr(self, 'sid') if not self_id: # this can happen when cache_region is already set by the class to # a persistent region self_id = self.generate_sid() else: self_id = self.uid # ensure that passing a value as positional or keyword argument does not matter kwargs.update(zip(argnames, args)) # ensure the values of optional parameters enter the cache key if defaults: kwargs = dict(defaults, **kwargs) key = generate_sid((method.__name__, self_id, kwargs, defaults_sid())) found, value = region.get(key) if found: return value else: self.logger.debug(f'creating new cache entry for {self.__class__.__name__}.{method.__name__}') value = method(self, **kwargs) if pass_self else method(**kwargs) region.set(key, value) return value
def jacobian(self, U, mu=None): if self.linear: return self.assemble(mu) if hasattr(self, '_assembled_operator'): if self._defaults_sid == defaults_sid(): return self._assembled_operator.jacobian(U) else: return self.assemble().jacobian(U) elif self._try_assemble: return self.assemble().jacobian(U) jacobians = [op.jacobian(U, mu) for op in self.operators] coefficients = self.evaluate_coefficients(mu) options = self.solver_options.get( 'jacobian') if self.solver_options else None jac = jacobians[0].assemble_lincomb( jacobians, coefficients, solver_options=options, name=self.name + '_jacobian') if jac is None: return LincombOperator( jacobians, coefficients, solver_options=options, name=self.name + '_jacobian') else: return jac
def jacobian(self, U, mu=None): if self.linear: return self.assemble(mu) if hasattr(self, '_assembled_operator'): if self._defaults_sid == defaults_sid(): return self._assembled_operator.jacobian(U) else: return self.assemble().jacobian(U) elif self._try_assemble: return self.assemble().jacobian(U) jacobians = [op.jacobian(U, mu) for op in self.operators] coefficients = self.evaluate_coefficients(mu) options = self.solver_options.get( 'jacobian') if self.solver_options else None jac = jacobians[0].assemble_lincomb(jacobians, coefficients, solver_options=options, name=self.name + '_jacobian') if jac is None: return LincombOperator(jacobians, coefficients, solver_options=options, name=self.name + '_jacobian') else: return jac
def apply2(self, V, U, U_ind=None, V_ind=None, mu=None, product=None): if hasattr(self, '_assembled_operator'): if self._defaults_sid == defaults_sid(): return self._assembled_operator.apply2(V, U, V_ind=V_ind, U_ind=U_ind, product=product) else: return self.assemble().apply2(V, U, V_ind=V_ind, U_ind=U_ind, product=product) elif self._try_assemble: return self.assemble().apply2(V, U, V_ind=V_ind, U_ind=U_ind, product=product) coeffs = self.evaluate_coefficients(mu) R = self.operators[0].apply2(V, U, V_ind=V_ind, U_ind=U_ind, mu=mu, product=product) R *= coeffs[0] for op, c in zip(self.operators[1:], coeffs[1:]): R += c * op.apply2( V, U, V_ind=V_ind, U_ind=U_ind, mu=mu, product=product) return R
def __call__(self, im_self, *args, **kwargs): """Via the magic that is partial functions returned from __get__, im_self is the instance object of the class we're decorating a method of and [kw]args are the actual parameters to the decorated method""" if not cache_regions: default_regions() try: region = cache_regions[im_self.cache_region] except KeyError: raise KeyError('No cache region "{}" found'.format(im_self.cache_region)) if not region.enabled: return self.decorated_function(im_self, *args, **kwargs) # ensure that passing a value as positional or keyword argument does not matter kwargs.update(zip(self.argnames, args)) # ensure the values of optional parameters enter the cache key defaults = self.defaults if defaults: kwargs = dict(defaults, **kwargs) key = generate_sid((self.decorated_function.__name__, getattr(im_self, 'sid', im_self.uid), kwargs, defaults_sid())) found, value = region.get(key) if found: return value else: im_self.logger.debug('creating new cache entry for {}.{}' .format(im_self.__class__.__name__, self.decorated_function.__name__)) value = self.decorated_function(im_self, **kwargs) region.set(key, value) return value
def _cached_method_call(self, method, pass_self, argnames, defaults, args, kwargs): if not cache_regions: default_regions() try: region = cache_regions[self.cache_region] except KeyError: raise KeyError('No cache region "{}" found'.format(self.cache_region)) # compute id for self if region.persistent: self_id = getattr(self, 'sid') if not self_id: # this can happen when cache_region is already set by the class to # a persistent region self_id = self.generate_sid() else: self_id = self.uid # ensure that passing a value as positional or keyword argument does not matter kwargs.update(zip(argnames, args)) # ensure the values of optional parameters enter the cache key if defaults: kwargs = dict(defaults, **kwargs) key = generate_sid((method.__name__, self_id, kwargs, defaults_sid())) found, value = region.get(key) if found: return value else: self.logger.debug('creating new cache entry for {}.{}' .format(self.__class__.__name__, method.__name__)) value = method(self, **kwargs) if pass_self else method(**kwargs) region.set(key, value) return value
def projected(self, range_basis, source_basis, product=None, name=None): if hasattr(self, '_assembled_operator'): if self._defaults_sid == defaults_sid(): return self._assembled_operator.projected(range_basis, source_basis, product, name) else: return self.assemble().projected(range_basis, source_basis, product, name) elif self._try_assemble: return self.assemble().projected(range_basis, source_basis, product, name) proj_operators = [op.projected(range_basis=range_basis, source_basis=source_basis, product=product) for op in self.operators] return self.with_(operators=proj_operators, name=name or self.name + '_projected')
def _options(matrix=None, sparse=None): """Returns |solver_options| (with default values) for a given |NumPy| matrix. See :func:`dense_options` for documentation of all possible options for dense matrices. See :func:`sparse_options` for documentation of all possible options for sparse matrices. Parameters ---------- matrix The matrix for which to return the options. sparse Instead of providing a matrix via the `matrix` argument, `sparse` can be set to `True` or `False` to requset the invert options for sparse or dense matrices. Returns ------- A tuple of all possible |solver_options|. """ global _dense_options, _dense_options_sid, _sparse_options, _sparse_options_sid assert (matrix is None) != (sparse is None) sparse = sparse if sparse is not None else issparse(matrix) if sparse: if not _sparse_options or _sparse_options_sid != defaults_sid(): _sparse_options = sparse_options() _sparse_options_sid = defaults_sid() return _sparse_options else: return _sparse_options else: if not _dense_options or _dense_options_sid != defaults_sid(): _dense_options = dense_options() _dense_options_sid = defaults_sid() return _dense_options else: return _dense_options
def apply2(self, V, U, mu=None): if hasattr(self, '_assembled_operator'): if self._defaults_sid == defaults_sid(): return self._assembled_operator.apply2(V, U) else: return self.assemble().apply2(V, U) elif self._try_assemble: return self.assemble().apply2(V, U) coeffs = self.evaluate_coefficients(mu) R = self.operators[0].apply2(V, U, mu=mu) R *= coeffs[0] for op, c in zip(self.operators[1:], coeffs[1:]): R += c * op.apply2(V, U, mu=mu) return R
def apply(self, U, ind=None, mu=None): if hasattr(self, '_assembled_operator'): if self._defaults_sid == defaults_sid(): return self._assembled_operator.apply(U, ind=ind) else: return self.assemble().apply(U, ind=ind) elif self._try_assemble: return self.assemble().apply(U, ind=ind) coeffs = self.evaluate_coefficients(mu) R = self.operators[0].apply(U, ind=ind, mu=mu) R.scal(coeffs[0]) for op, c in izip(self.operators[1:], coeffs[1:]): R.axpy(c, op.apply(U, ind=ind, mu=mu)) return R
def as_vector(self, mu=None): if hasattr(self, '_assembled_operator'): if self._defaults_sid == defaults_sid(): return self._assembled_operator.as_vector() else: return self.assemble().as_vector() elif self._try_assemble: return self.assemble().as_vector() coefficients = np.array(self.evaluate_coefficients(mu)) vectors = [op.as_vector(mu) for op in self.operators] R = vectors[0] R.scal(coefficients[0]) for c, v in izip(coefficients[1:], vectors[1:]): R.axpy(c, v) return R
def as_vector(self, mu=None): if hasattr(self, '_assembled_operator'): if self._defaults_sid == defaults_sid(): return self._assembled_operator.as_vector() else: return self.assemble().as_vector() elif self._try_assemble: return self.assemble().as_vector() coefficients = self.evaluate_coefficients(mu) vectors = [op.as_vector(mu) for op in self.operators] R = vectors[0] R.scal(coefficients[0]) for c, v in izip(coefficients[1:], vectors[1:]): R.axpy(c, v) return R
def _as_array(self, source, mu): if hasattr(self, '_assembled_operator'): if self._defaults_sid == defaults_sid(): return self._assembled_operator.as_source_array() if source \ else self._assembled_operator.as_range_array() else: return self.assemble().as_source_array() if source else self.assemble().as_range_array() elif self._try_assemble: return self.assemble().as_source_array() if source else self.assemble().as_range_array() coefficients = np.array(self.evaluate_coefficients(mu)) arrays = [op.as_source_array(mu) if source else op.as_range_array(mu) for op in self.operators] R = arrays[0] R.scal(coefficients[0]) for c, v in zip(coefficients[1:], arrays[1:]): R.axpy(c, v) return R
def projected(self, source_basis, range_basis, product=None, name=None): if hasattr(self, '_assembled_operator'): if self._defaults_sid == defaults_sid(): return self._assembled_operator.projected( source_basis, range_basis, product, name) else: return self.assemble().projected(source_basis, range_basis, product, name) elif self._try_assemble: return self.assemble().projected(source_basis, range_basis, product, name) proj_operators = [ op.projected(source_basis=source_basis, range_basis=range_basis, product=product) for op in self.operators ] return self.with_(operators=proj_operators, name=name or self.name + '_projected')
def apply_adjoint(self, U, ind=None, mu=None, source_product=None, range_product=None): if hasattr(self, '_assembled_operator'): if self._defaults_sid == defaults_sid(): return self._assembled_operator.apply_adjoint(U, ind=ind, source_product=source_product, range_product=range_product) else: return self.assemble().apply_adjoint(U, ind=ind, source_product=source_product, range_product=range_product) elif self._try_assemble: return self.assemble().apply_adjoint(U, ind=ind, source_product=source_product, range_product=range_product) coeffs = self.evaluate_coefficients(mu) R = self.operators[0].apply_adjoint(U, ind=ind, mu=mu, source_product=source_product, range_product=range_product) R.scal(coeffs[0]) for op, c in izip(self.operators[1:], coeffs[1:]): R.axpy(c, op.apply_adjoint(U, ind=ind, mu=mu, source_product=source_product, range_product=range_product)) return R
def _call(self, *args, **kwargs): instance = super(ImmutableMeta, self).__call__(*args, **kwargs) if instance.calculate_sid: try: arguments = instance._init_defaults.copy() arguments.update(kwargs) arguments.update((k, o) for k, o in itertools.izip(instance._init_arguments, args)) arguments_sids = tuple((k, _calculate_sid(o, k)) for k, o in sorted(arguments.iteritems()) if k not in instance.sid_ignore) instance.sid = (type(instance), arguments_sids, defaults_sid()) ImmutableMeta.sids_created += 1 except ValueError as e: instance.sid_failure = str(e) else: instance.sid_failure = 'disabled' instance._locked = True return instance
def __call__(self, im_self, *args, **kwargs): """Via the magic that is partial functions returned from __get__, im_self is the instance object of the class we're decorating a method of and [kw]args are the actual parameters to the decorated method""" region = cache_regions[im_self.cache_region] if not region.enabled: return self.decorated_function(im_self, *args, **kwargs) key = (self.decorated_function.__name__, getattr(im_self, 'sid', im_self.uid), tuple(getattr(x, 'sid', x) for x in args), tuple((k, getattr(v, 'sid', v)) for k, v in sorted(kwargs.iteritems())), defaults_sid()) key = dumps(key) found, value = region.get(key) if found: return value else: im_self.logger.debug('creating new cache entry for {}.{}' .format(im_self.__class__.__name__, self.decorated_function.__name__)) value = self.decorated_function(im_self, *args, **kwargs) region.set(key, value) return value
def apply_adjoint(self, U, ind=None, mu=None, source_product=None, range_product=None): if hasattr(self, '_assembled_operator'): if self._defaults_sid == defaults_sid(): return self._assembled_operator.apply_adjoint( U, ind=ind, source_product=source_product, range_product=range_product) else: return self.assemble().apply_adjoint( U, ind=ind, source_product=source_product, range_product=range_product) elif self._try_assemble: return self.assemble().apply_adjoint(U, ind=ind, source_product=source_product, range_product=range_product) coeffs = self.evaluate_coefficients(mu) R = self.operators[0].apply_adjoint(U, ind=ind, mu=mu, source_product=source_product, range_product=range_product) R.scal(coeffs[0]) for op, c in izip(self.operators[1:], coeffs[1:]): R.axpy( c, op.apply_adjoint(U, ind=ind, mu=mu, source_product=source_product, range_product=range_product)) return R
def _call(self, *args, **kwargs): instance = super(ImmutableMeta, self).__call__(*args, **kwargs) if instance.calculate_sid: try: arguments = instance._init_defaults.copy() arguments.update(kwargs) arguments.update( (k, o) for k, o in itertools.izip(instance._init_arguments, args)) arguments_sids = tuple( (k, _calculate_sid(o, k)) for k, o in sorted(arguments.iteritems()) if k not in instance.sid_ignore) instance.sid = (type(instance), arguments_sids, defaults_sid()) ImmutableMeta.sids_created += 1 except ValueError as e: instance.sid_failure = str(e) else: instance.sid_failure = 'disabled' instance._locked = True return instance
def inject_sid(obj, context, *args): """Add a state id sid to an object. The purpose of this methods is to inject state ids into objects which do not derive from :class:`ImmutableInterface`. If `obj` is an instance of :class:`BasicInterface`, it is locked, if it is an :class:`numpy.ndarray`, its `writable` flag is set to `False`. It is the callers responsibility to ensure that the given parameters uniquely describe the state of `obj`, and that `obj` does not change its state after the call of `inject_sid`. For an example see :class:`pymor.analyticalproblems.EllipticProblem`. Parameters ---------- obj The object which shall obtain a sid. context A hashable, picklable, immutable object, describing the context in which `obj` was created. `*args` List of parameters which in the given context led to the creation of `obj`. """ try: sid = tuple( (context, tuple(_calculate_sid(o, i) for i, o in enumerate(args)), defaults_sid())) obj.sid = sid ImmutableMeta.sids_created += 1 except ValueError as e: obj.sid_failure = str(e) if isinstance(obj, BasicInterface): obj.lock() elif isinstance(obj, np.ndarray): obj.flags.writable = False
def invert_options(default_solver='generic_lgmres', default_least_squares_solver='least_squares_generic_lsmr', generic_lgmres_tol=1e-5, generic_lgmres_maxiter=1000, generic_lgmres_inner_m=39, generic_lgmres_outer_k=3, least_squares_generic_lsmr_damp=0.0, least_squares_generic_lsmr_atol=1e-6, least_squares_generic_lsmr_btol=1e-6, least_squares_generic_lsmr_conlim=1e8, least_squares_generic_lsmr_maxiter=None, least_squares_generic_lsmr_show=False, least_squares_generic_lsqr_damp=0.0, least_squares_generic_lsqr_atol=1e-6, least_squares_generic_lsqr_btol=1e-6, least_squares_generic_lsqr_conlim=1e8, least_squares_generic_lsqr_iter_lim=None, least_squares_generic_lsqr_show=False): """Returns |invert_options| (with default values) for arbitrary linear |Operators|. Parameters ---------- default_solver Default solver to use (generic_lgmres, least_squares_generic_lsmr, least_squares_generic_lsqr). default_least_squares_solver Default solver to use for least squares problems (least_squares_generic_lsmr, least_squares_generic_lsqr). generic_lgmres_tol See :func:`scipy.sparse.linalg.lgmres`. generic_lgmres_maxiter See :func:`scipy.sparse.linalg.lgmres`. generic_lgmres_inner_m See :func:`scipy.sparse.linalg.lgmres`. generic_lgmres_outer_k See :func:`scipy.sparse.linalg.lgmres`. least_squares_generic_lsmr_damp See :func:`scipy.sparse.linalg.lsmr`. least_squares_generic_lsmr_atol See :func:`scipy.sparse.linalg.lsmr`. least_squares_generic_lsmr_btol See :func:`scipy.sparse.linalg.lsmr`. least_squares_generic_lsmr_conlim See :func:`scipy.sparse.linalg.lsmr`. least_squares_generic_lsmr_maxiter See :func:`scipy.sparse.linalg.lsmr`. least_squares_generic_lsmr_show See :func:`scipy.sparse.linalg.lsmr`. least_squares_generic_lsqr_damp See :func:`scipy.sparse.linalg.lsqr`. least_squares_generic_lsqr_atol See :func:`scipy.sparse.linalg.lsqr`. least_squares_generic_lsqr_btol See :func:`scipy.sparse.linalg.lsqr`. least_squares_generic_lsqr_conlim See :func:`scipy.sparse.linalg.lsqr`. least_squares_generic_lsqr_iter_lim See :func:`scipy.sparse.linalg.lsqr`. least_squares_generic_lsqr_show See :func:`scipy.sparse.linalg.lsqr`. Returns ------- A tuple of all possible |invert_options|. """ assert default_least_squares_solver.startswith('least_squares') global _options, _options_sid if _options and _options_sid == defaults_sid(): return _options opts = (('generic_lgmres', {'type': 'generic_lgmres', 'tol': generic_lgmres_tol, 'maxiter': generic_lgmres_maxiter, 'inner_m': generic_lgmres_inner_m, 'outer_k': generic_lgmres_outer_k}), ('least_squares_generic_lsmr', {'type': 'least_squares_generic_lsmr', 'damp': least_squares_generic_lsmr_damp, 'atol': least_squares_generic_lsmr_atol, 'btol': least_squares_generic_lsmr_btol, 'conlim': least_squares_generic_lsmr_conlim, 'maxiter': least_squares_generic_lsmr_maxiter, 'show': least_squares_generic_lsmr_show}), ('least_squares_generic_lsqr', {'type': 'least_squares_generic_lsqr', 'damp': least_squares_generic_lsqr_damp, 'atol': least_squares_generic_lsqr_atol, 'btol': least_squares_generic_lsqr_btol, 'conlim': least_squares_generic_lsqr_conlim, 'iter_lim': least_squares_generic_lsqr_iter_lim, 'show': least_squares_generic_lsqr_show})) opts = OrderedDict(opts) def_opt = opts.pop(default_solver) if default_least_squares_solver != default_solver: def_ls_opt = opts.pop(default_least_squares_solver) _options = OrderedDict(((default_solver, def_opt), (default_least_squares_solver, def_ls_opt))) else: _options = OrderedDict(((default_solver, def_opt),)) _options.update(opts) _options_sid = defaults_sid() return _options
def inject_sid(obj, context, *args): """Add a state id sid to an object. The purpose of this methods is to inject state ids into objects which do not derive from :class:`ImmutableInterface`. If `obj` is an instance of :class:`BasicInterface`, it is locked, if it is an :class:`numpy.ndarray`, its `writable` flag is set to `False`. It is the callers responsibility to ensure that the given parameters uniquely describe the state of `obj`, and that `obj` does not change its state after the call of `inject_sid`. For an example see :class:`pymor.analyticalproblems.EllipticProblem`. Parameters ---------- obj The object which shall obtain a sid. context A hashable, picklable, immutable object, describing the context in which `obj` was created. `*args` List of parameters which in the given context led to the creation of `obj`. """ try: sid = tuple((context, tuple(_calculate_sid(o, i) for i, o in enumerate(args)), defaults_sid())) obj.sid = sid ImmutableMeta.sids_created += 1 except ValueError as e: obj.sid_failure = str(e) if isinstance(obj, BasicInterface): obj.lock() elif isinstance(obj, np.ndarray): obj.flags.writable = False
def options(default_solver='generic_lgmres', default_least_squares_solver='least_squares_generic_lsmr', generic_lgmres_tol=1e-5, generic_lgmres_maxiter=1000, generic_lgmres_inner_m=39, generic_lgmres_outer_k=3, least_squares_generic_lsmr_damp=0.0, least_squares_generic_lsmr_atol=1e-6, least_squares_generic_lsmr_btol=1e-6, least_squares_generic_lsmr_conlim=1e8, least_squares_generic_lsmr_maxiter=None, least_squares_generic_lsmr_show=False, least_squares_generic_lsqr_damp=0.0, least_squares_generic_lsqr_atol=1e-6, least_squares_generic_lsqr_btol=1e-6, least_squares_generic_lsqr_conlim=1e8, least_squares_generic_lsqr_iter_lim=None, least_squares_generic_lsqr_show=False): """Returns |solver_options| (with default values) for arbitrary linear |Operators|. Parameters ---------- default_solver Default solver to use (generic_lgmres, least_squares_generic_lsmr, least_squares_generic_lsqr). default_least_squares_solver Default solver to use for least squares problems (least_squares_generic_lsmr, least_squares_generic_lsqr). generic_lgmres_tol See :func:`scipy.sparse.linalg.lgmres`. generic_lgmres_maxiter See :func:`scipy.sparse.linalg.lgmres`. generic_lgmres_inner_m See :func:`scipy.sparse.linalg.lgmres`. generic_lgmres_outer_k See :func:`scipy.sparse.linalg.lgmres`. least_squares_generic_lsmr_damp See :func:`scipy.sparse.linalg.lsmr`. least_squares_generic_lsmr_atol See :func:`scipy.sparse.linalg.lsmr`. least_squares_generic_lsmr_btol See :func:`scipy.sparse.linalg.lsmr`. least_squares_generic_lsmr_conlim See :func:`scipy.sparse.linalg.lsmr`. least_squares_generic_lsmr_maxiter See :func:`scipy.sparse.linalg.lsmr`. least_squares_generic_lsmr_show See :func:`scipy.sparse.linalg.lsmr`. least_squares_generic_lsqr_damp See :func:`scipy.sparse.linalg.lsqr`. least_squares_generic_lsqr_atol See :func:`scipy.sparse.linalg.lsqr`. least_squares_generic_lsqr_btol See :func:`scipy.sparse.linalg.lsqr`. least_squares_generic_lsqr_conlim See :func:`scipy.sparse.linalg.lsqr`. least_squares_generic_lsqr_iter_lim See :func:`scipy.sparse.linalg.lsqr`. least_squares_generic_lsqr_show See :func:`scipy.sparse.linalg.lsqr`. Returns ------- A tuple of possible values for |solver_options|. """ assert default_least_squares_solver.startswith('least_squares') global _options, _options_sid if _options and _options_sid == defaults_sid(): return _options opts = (('generic_lgmres', { 'type': 'generic_lgmres', 'tol': generic_lgmres_tol, 'maxiter': generic_lgmres_maxiter, 'inner_m': generic_lgmres_inner_m, 'outer_k': generic_lgmres_outer_k }), ('least_squares_generic_lsmr', { 'type': 'least_squares_generic_lsmr', 'damp': least_squares_generic_lsmr_damp, 'atol': least_squares_generic_lsmr_atol, 'btol': least_squares_generic_lsmr_btol, 'conlim': least_squares_generic_lsmr_conlim, 'maxiter': least_squares_generic_lsmr_maxiter, 'show': least_squares_generic_lsmr_show }), ('least_squares_generic_lsqr', { 'type': 'least_squares_generic_lsqr', 'damp': least_squares_generic_lsqr_damp, 'atol': least_squares_generic_lsqr_atol, 'btol': least_squares_generic_lsqr_btol, 'conlim': least_squares_generic_lsqr_conlim, 'iter_lim': least_squares_generic_lsqr_iter_lim, 'show': least_squares_generic_lsqr_show })) opts = OrderedDict(opts) def_opt = opts.pop(default_solver) if default_least_squares_solver != default_solver: def_ls_opt = opts.pop(default_least_squares_solver) _options = OrderedDict(((default_solver, def_opt), (default_least_squares_solver, def_ls_opt))) else: _options = OrderedDict(((default_solver, def_opt), )) _options.update(opts) _options_sid = defaults_sid() return _options
def invert_options( default_solver="generic_lgmres", default_least_squares_solver="least_squares_generic_lsmr", generic_lgmres_tol=1e-5, generic_lgmres_maxiter=1000, generic_lgmres_inner_m=39, generic_lgmres_outer_k=3, least_squares_generic_lsmr_damp=0.0, least_squares_generic_lsmr_atol=1e-6, least_squares_generic_lsmr_btol=1e-6, least_squares_generic_lsmr_conlim=1e8, least_squares_generic_lsmr_maxiter=None, least_squares_generic_lsmr_show=False, least_squares_generic_lsqr_damp=0.0, least_squares_generic_lsqr_atol=1e-6, least_squares_generic_lsqr_btol=1e-6, least_squares_generic_lsqr_conlim=1e8, least_squares_generic_lsqr_iter_lim=None, least_squares_generic_lsqr_show=False, ): """Returns |invert_options| (with default values) for arbitrary linear |Operators|. Parameters ---------- default_solver Default solver to use (generic_lgmres, least_squares_generic_lsmr, least_squares_generic_lsqr). default_least_squares_solver Default solver to use for least squares problems (least_squares_generic_lsmr, least_squares_generic_lsqr). generic_lgmres_tol See :func:`scipy.sparse.linalg.lgmres`. generic_lgmres_maxiter See :func:`scipy.sparse.linalg.lgmres`. generic_lgmres_inner_m See :func:`scipy.sparse.linalg.lgmres`. generic_lgmres_outer_k See :func:`scipy.sparse.linalg.lgmres`. least_squares_generic_lsmr_damp See :func:`scipy.sparse.linalg.lsmr`. least_squares_generic_lsmr_atol See :func:`scipy.sparse.linalg.lsmr`. least_squares_generic_lsmr_btol See :func:`scipy.sparse.linalg.lsmr`. least_squares_generic_lsmr_conlim See :func:`scipy.sparse.linalg.lsmr`. least_squares_generic_lsmr_maxiter See :func:`scipy.sparse.linalg.lsmr`. least_squares_generic_lsmr_show See :func:`scipy.sparse.linalg.lsmr`. least_squares_generic_lsqr_damp See :func:`scipy.sparse.linalg.lsqr`. least_squares_generic_lsqr_atol See :func:`scipy.sparse.linalg.lsqr`. least_squares_generic_lsqr_btol See :func:`scipy.sparse.linalg.lsqr`. least_squares_generic_lsqr_conlim See :func:`scipy.sparse.linalg.lsqr`. least_squares_generic_lsqr_iter_lim See :func:`scipy.sparse.linalg.lsqr`. least_squares_generic_lsqr_show See :func:`scipy.sparse.linalg.lsqr`. Returns ------- A tuple of all possible |invert_options|. """ assert default_least_squares_solver.startswith("least_squares") global _options, _options_sid if _options and _options_sid == defaults_sid(): return _options opts = ( ( "generic_lgmres", { "type": "generic_lgmres", "tol": generic_lgmres_tol, "maxiter": generic_lgmres_maxiter, "inner_m": generic_lgmres_inner_m, "outer_k": generic_lgmres_outer_k, }, ), ( "least_squares_generic_lsmr", { "type": "least_squares_generic_lsmr", "damp": least_squares_generic_lsmr_damp, "atol": least_squares_generic_lsmr_atol, "btol": least_squares_generic_lsmr_btol, "conlim": least_squares_generic_lsmr_conlim, "maxiter": least_squares_generic_lsmr_maxiter, "show": least_squares_generic_lsmr_show, }, ), ( "least_squares_generic_lsqr", { "type": "least_squares_generic_lsqr", "damp": least_squares_generic_lsqr_damp, "atol": least_squares_generic_lsqr_atol, "btol": least_squares_generic_lsqr_btol, "conlim": least_squares_generic_lsqr_conlim, "iter_lim": least_squares_generic_lsqr_iter_lim, "show": least_squares_generic_lsqr_show, }, ), ) opts = OrderedDict(opts) def_opt = opts.pop(default_solver) if default_least_squares_solver != default_solver: def_ls_opt = opts.pop(default_least_squares_solver) _options = OrderedDict(((default_solver, def_opt), (default_least_squares_solver, def_ls_opt))) else: _options = OrderedDict(((default_solver, def_opt),)) _options.update(opts) _options_sid = defaults_sid() return _options