agd.Metrics

The Metrics package defines a variety of norms on R^d, defined by appropriate parameters, possibly non-symmetric. The data of a such a norm, at each point of a domain, is referred to as a metric, for instance a Riemannian metric, and defines a path-length distance over the domain.

Metrics are the fundamental input to (generalized) eikonal equations, which can be solved using the provided Eikonal module.

Main norm/metric classes:

  • Isotropic : a multiple of the Euclidean norm on $R^d$.
  • Diagonal : axis-dependent multiple of the Euclidean norm.
  • Riemann : anisotropic norm on $R^d$ defined by a symmetric positice definite matrix of shape $(d,d)$. Used to define a Riemannian metric.
  • Rander : non-symmetric anisotropic norm, defined as the sum of a Riemann norm and of a drift term.
  • AsymQuad : non-symmetric anisotropic norm, defined by gluing two Riemann norms along a hyperplane.

Additional norm/metric classes are defined in the Seismic subpackage.

 1# Copyright 2020 Jean-Marie Mirebeau, University Paris-Sud, CNRS, University Paris-Saclay
 2# Distributed WITHOUT ANY WARRANTY. Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0
 3
 4"""
 5The Metrics package defines a variety of norms on R^d, defined by appropriate parameters,
 6possibly non-symmetric. The data of a such a norm, at each point of a domain, is referred 
 7to as a metric, for instance a Riemannian metric, and defines a path-length distance 
 8over the domain.
 9
10Metrics are the fundamental input to (generalized) eikonal equations, which can be solved
11using the provided Eikonal module.
12
13Main norm/metric classes:
14- Isotropic : a multiple of the Euclidean norm on $R^d$.
15- Diagonal : axis-dependent multiple of the Euclidean norm.
16- Riemann : anisotropic norm on $R^d$ defined by a symmetric positice definite matrix of 
17 shape $(d,d)$. Used to define a Riemannian metric.
18- Rander : non-symmetric anisotropic norm, defined as the sum of a Riemann norm and 
19 of a drift term.
20- AsymQuad : non-symmetric anisotropic norm, defined by gluing two Riemann norms along 
21 a hyperplane.
22
23Additional norm/metric classes are defined in the Seismic subpackage.
24"""
25
26
27from .base 	    import Base
28from .isotropic import Isotropic
29from .diagonal  import Diagonal 
30from .riemann 	import Riemann
31from .rander    import Rander
32from .asym_quad import AsymQuad
33
34def make_metric(m=None,w=None,a=None,w_rander=None,geometry_last=False):
35    """
36    Defines the metric F(x) = sqrt(a^2 x.m.x + sign(a)(w.x)_+^2) + w_rander.x,
37    with expected defauts for m,w,a,w_rander.
38    """
39    from .. import Metrics
40    if geometry_last:
41        if m is not None: m = np.moveaxis(m,(-2,-1),(0,1))
42        if w is not None: w = np.moveaxis(w,-1,0)
43        if w_rander is not None: w_rander = np.moveaxis(w_rander,-1,0)
44    if m is None:
45        if w is None: return Isotropic(np.abs(a))
46        vdim = len(w)
47        m = np.broadcast_to(np.eye(vdim,like=w),(vdim,*w.shape))
48    if a is not None: 
49        if not overwrite_m: 
50            m = m.copy()
51            if w is not None: w = w.copy()
52        m *= a**2
53        if w is not None:
54            pos = a<0
55            w[pos] *= -1
56            #m[pos] -= np.outer(w[pos],w[pos]) # Some issues with empty shapes
57            m -= pos*np.outer(w,w)
58    if w is None: 
59        if w_rander is None: return Riemann(m)
60        else: return Metrics.Rander(m,w_rander)
61    if w_rander is None: return AsymQuad(m,w)
62    else:
63        from .asym_rander import AsymRander
64        return AsymRander(m,w,None,w_rander)
def make_metric(m=None, w=None, a=None, w_rander=None, geometry_last=False):
35def make_metric(m=None,w=None,a=None,w_rander=None,geometry_last=False):
36    """
37    Defines the metric F(x) = sqrt(a^2 x.m.x + sign(a)(w.x)_+^2) + w_rander.x,
38    with expected defauts for m,w,a,w_rander.
39    """
40    from .. import Metrics
41    if geometry_last:
42        if m is not None: m = np.moveaxis(m,(-2,-1),(0,1))
43        if w is not None: w = np.moveaxis(w,-1,0)
44        if w_rander is not None: w_rander = np.moveaxis(w_rander,-1,0)
45    if m is None:
46        if w is None: return Isotropic(np.abs(a))
47        vdim = len(w)
48        m = np.broadcast_to(np.eye(vdim,like=w),(vdim,*w.shape))
49    if a is not None: 
50        if not overwrite_m: 
51            m = m.copy()
52            if w is not None: w = w.copy()
53        m *= a**2
54        if w is not None:
55            pos = a<0
56            w[pos] *= -1
57            #m[pos] -= np.outer(w[pos],w[pos]) # Some issues with empty shapes
58            m -= pos*np.outer(w,w)
59    if w is None: 
60        if w_rander is None: return Riemann(m)
61        else: return Metrics.Rander(m,w_rander)
62    if w_rander is None: return AsymQuad(m,w)
63    else:
64        from .asym_rander import AsymRander
65        return AsymRander(m,w,None,w_rander)

Defines the metric F(x) = sqrt(a^2 x.m.x + sign(a)(w.x)_+^2) + w_rander.x, with expected defauts for m,w,a,w_rander.