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

more

parent 393327d5
......@@ -20,10 +20,10 @@ import numpy as np
from . import utilities
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.
Stores data arrays and carries all the needed meta-information (i.e. the
......
......@@ -19,10 +19,10 @@ import numpy as np
from .sugar import makeOp
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
of the operator application (i.e. `A(x)`), the local Jacobian
(i.e. `dA(x)/dx`) and, optionally, the local metric.
......
......@@ -21,10 +21,10 @@ from . import utilities
from .field import Field
from .multi_domain import MultiDomain
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):
"""The discrete representation of a continuous field over a sum space.
......
......@@ -169,8 +169,8 @@ class LinearOperator(Operator):
raise NotImplementedError
def __call__(self, x):
"""Same as :meth:`times`"""
from ..linearization import Linearization
if isinstance(x, Operator):
return self @ x
if x.jac is not None:
return x.new(self(x.fld), self).prepend_jac(x.jac)
if x.val is not None:
......
......@@ -46,75 +46,6 @@ class Operator(metaclass=NiftyMeta):
"""
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
def _check_domain_equality(dom_op, dom_field):
if dom_op != dom_field:
......@@ -240,7 +171,8 @@ class Operator(metaclass=NiftyMeta):
def _check_input(self, x):
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
if x.jac is not None:
if not isinstance(x.jac, ScalingOperator):
......@@ -250,13 +182,14 @@ class Operator(metaclass=NiftyMeta):
self._check_domain_equality(self._domain, x.domain)
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
if x.jac is not None:
return self.apply(x.trivial_jac()).prepend_jac(x.jac)
elif x.val is not None:
return self.apply(x)
return self @ x
return self.apply(x)
def ducktape(self, name):
from .simple_linear_operators import ducktape
......
......@@ -98,6 +98,9 @@ class ScalingOperator(EndomorphicOperator):
def __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 other.jac 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