Commit d19a916d authored by Martin Reinecke's avatar Martin Reinecke
Browse files

more

parent 393327d5
...@@ -20,10 +20,10 @@ import numpy as np ...@@ -20,10 +20,10 @@ import numpy as np
from . import utilities from . import utilities
from .domain_tuple import DomainTuple from .domain_tuple import DomainTuple
from .operators.operator import Operator from .operand import Operand
class Field(Operator): class Field(Operand):
"""The discrete representation of a continuous field over multiple spaces. """The discrete representation of a continuous field over multiple spaces.
Stores data arrays and carries all the needed meta-information (i.e. the Stores data arrays and carries all the needed meta-information (i.e. the
......
...@@ -19,10 +19,10 @@ import numpy as np ...@@ -19,10 +19,10 @@ import numpy as np
from .sugar import makeOp from .sugar import makeOp
from . import utilities from . import utilities
from .operators.operator import Operator from .operand import Operand
class Linearization(Operator): class Linearization(Operand):
"""Let `A` be an operator and `x` a field. `Linearization` stores the value """Let `A` be an operator and `x` a field. `Linearization` stores the value
of the operator application (i.e. `A(x)`), the local Jacobian of the operator application (i.e. `A(x)`), the local Jacobian
(i.e. `dA(x)/dx`) and, optionally, the local metric. (i.e. `dA(x)/dx`) and, optionally, the local metric.
......
...@@ -21,10 +21,10 @@ from . import utilities ...@@ -21,10 +21,10 @@ from . import utilities
from .field import Field from .field import Field
from .multi_domain import MultiDomain from .multi_domain import MultiDomain
from .domain_tuple import DomainTuple from .domain_tuple import DomainTuple
from .operators.operator import Operator from .operand import Operand
class MultiField(Operator): class MultiField(Operand):
def __init__(self, domain, val): def __init__(self, domain, val):
"""The discrete representation of a continuous field over a sum space. """The discrete representation of a continuous field over a sum space.
......
...@@ -169,8 +169,8 @@ class LinearOperator(Operator): ...@@ -169,8 +169,8 @@ class LinearOperator(Operator):
raise NotImplementedError raise NotImplementedError
def __call__(self, x): def __call__(self, x):
"""Same as :meth:`times`""" if isinstance(x, Operator):
from ..linearization import Linearization return self @ x
if x.jac is not None: if x.jac is not None:
return x.new(self(x.fld), self).prepend_jac(x.jac) return x.new(self(x.fld), self).prepend_jac(x.jac)
if x.val is not None: if x.val is not None:
......
...@@ -46,75 +46,6 @@ class Operator(metaclass=NiftyMeta): ...@@ -46,75 +46,6 @@ class Operator(metaclass=NiftyMeta):
""" """
return self._target return self._target
@property
def fld(self):
"""The field associated with this object
For "pure" operators this is `None`. For Field-like objects this
is a `Field` or a `MultiField` matching the object's `target`.
Returns
-------
None or Field or MultiField : the field object
"""
return None
@property
def val(self):
"""The numerical value associated with this object
For "pure" operators this is `None`. For Field-like objects this
is a `numpy.ndarray` or a dictionary of `numpy.ndarray`s matching the
object's `target`.
Returns
-------
None or numpy.ndarray or dictionary of np.ndarrays : the numerical value
"""
return None
@property
def jac(self):
"""The Jacobian associated with this object
For "pure" operators this is `None`. For Field-like objects this
can be `None` (in which case the object is a constant), or it can be a
`LinearOperator` with `domain` and `target` matching the object's.
Returns
-------
None or LinearOperator : the Jacobian
Notes
-----
if `value` is None, this must be `None` as well!
"""
return None
@property
def want_metric(self):
"""Whether a metric should be computed for the full expression.
This is `False` whenever `jac` is `None`. In other cases it signals
that operators processing this object should compute the metric.
Returns
-------
bool : whether the metric should be computed
"""
return False
@property
def metric(self):
"""The metric associated with the object.
This is `None`, except when all the following conditions hold:
- `want_metric` is `True`
- `target` is the scalar domain
- the operator chain contained an operator which could compute the
metric
Returns
-------
None or LinearOperator : the metric
"""
return None
@staticmethod @staticmethod
def _check_domain_equality(dom_op, dom_field): def _check_domain_equality(dom_op, dom_field):
if dom_op != dom_field: if dom_op != dom_field:
...@@ -240,7 +171,8 @@ class Operator(metaclass=NiftyMeta): ...@@ -240,7 +171,8 @@ class Operator(metaclass=NiftyMeta):
def _check_input(self, x): def _check_input(self, x):
from .scaling_operator import ScalingOperator from .scaling_operator import ScalingOperator
if not (isinstance(x, Operator) and x.val is not None): from ..operand import Operand
if not isinstance(x, Operand):
raise TypeError raise TypeError
if x.jac is not None: if x.jac is not None:
if not isinstance(x.jac, ScalingOperator): if not isinstance(x.jac, ScalingOperator):
...@@ -250,13 +182,14 @@ class Operator(metaclass=NiftyMeta): ...@@ -250,13 +182,14 @@ class Operator(metaclass=NiftyMeta):
self._check_domain_equality(self._domain, x.domain) self._check_domain_equality(self._domain, x.domain)
def __call__(self, x): def __call__(self, x):
if not isinstance(x, Operator): if isinstance(x, Operator):
return self @ x
from ..operand import Operand
if not isinstance(x, Operand):
raise TypeError raise TypeError
if x.jac is not None: if x.jac is not None:
return self.apply(x.trivial_jac()).prepend_jac(x.jac) return self.apply(x.trivial_jac()).prepend_jac(x.jac)
elif x.val is not None: return self.apply(x)
return self.apply(x)
return self @ x
def ducktape(self, name): def ducktape(self, name):
from .simple_linear_operators import ducktape from .simple_linear_operators import ducktape
......
...@@ -98,6 +98,9 @@ class ScalingOperator(EndomorphicOperator): ...@@ -98,6 +98,9 @@ class ScalingOperator(EndomorphicOperator):
def __call__(self, other): def __call__(self, other):
res = EndomorphicOperator.__call__(self, other) res = EndomorphicOperator.__call__(self, other)
from .operator import Operator
if isinstance(res, Operator):
return res
if np.isreal(self._factor) and self._factor >= 0: if np.isreal(self._factor) and self._factor >= 0:
if other.jac is not None: if other.jac is not None:
if other.metric is not None: if other.metric is not None:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment