
    h                     6   S r SSKrSSKJr  SSKJr  SSKJr  SSK	J
r
  Sr " S S	5      r " S
 S\5      r " S S\5      r " S S5      r " S S5      r " S S\5      r " S S\5      r " S S\5      r " S S5      rS"S jrS rS rS rS rS rS  rS! rg)#z(
Interpolation inside triangular grids.
    N)_api)Triangulation)	TriFinder)TriAnalyzer)TriInterpolatorLinearTriInterpolatorCubicTriInterpolatorc                   >    \ rS rSrSrS
S jrSrSr  SS jrS r	S	r
g)r      a=  
Abstract base class for classes used to interpolate on a triangular grid.

Derived classes implement the following methods:

- ``__call__(x, y)``,
  where x, y are array-like point coordinates of the same shape, and
  that returns a masked array of the same shape containing the
  interpolated z-values.

- ``gradient(x, y)``,
  where x, y are array-like point coordinates of the same
  shape, and that returns a list of 2 masked arrays of the same shape
  containing the 2 derivatives of the interpolator (derivatives of
  interpolated z values with respect to x and y).
Nc                    [         R                  " [        US9  Xl        [        R
                  " U5      U l        U R                  R                  U R                  R                  R                  :w  a  [        S5      e[         R                  " [        S 4US9  U=(       d    U R                  R                  5       U l        SU l        SU l        S U l        g )N)triangulationz=z array must have same length as triangulation x and y arrays)	trifinder      ?)r   check_isinstancer   _triangulationnpasarray_zshapex
ValueErrorr   get_trifinder
_trifinder_unit_x_unit_y
_tri_renum)selfr   zr   s       P/var/www/html/env/lib/python3.13/site-packages/matplotlib/tri/_triinterpolate.py__init__TriInterpolator.__init__!   s    m=I+**Q-77==D//11777 - . . 	y$/9E#Jt':':'H'H'J      a  
        Returns a masked array containing interpolated values at the specified
        (x, y) points.

        Parameters
        ----------
        x, y : array-like
            x and y coordinates of the same shape and any number of
            dimensions.

        Returns
        -------
        np.ma.array
            Masked array of the same shape as *x* and *y*; values corresponding
            to (*x*, *y*) points outside of the triangulation are masked out.

        a  
        Returns a list of 2 masked arrays containing interpolated derivatives
        at the specified (x, y) points.

        Parameters
        ----------
        x, y : array-like
            x and y coordinates of the same shape and any number of
            dimensions.

        Returns
        -------
        dzdx, dzdy : np.ma.array
            2 masked arrays of the same shape as *x* and *y*; values
            corresponding to (x, y) points outside of the triangulation
            are masked out.
            The first returned array contains the values of
            :math:`\frac{\partial z}{\partial x}` and the second those of
            :math:`\frac{\partial z}{\partial y}`.

        c                    [         R                  " U[         R                  S9n[         R                  " U[         R                  S9nUR                  nUR                  UR                  :w  a%  [	        SUR                   SUR                   35      e[         R
                  " U5      n[         R
                  " U5      nXR                  -  nX R                  -  n[         R                  " U5      nUc  U R                  X5      nOAUR                  U:w  a  [	        SUR                   SU 35      e[         R
                  " U5      nUS:g  n	U R                  c  X9   n
OU R                  X9      n
Xi   nXy   n/ nU H  n SSS	S
.U   nSSU R                  -  SU R                  -  /U   n[         R                  " U[         R                  S9n[         R                  UU	) '   U R                  XX5      U-  UU	'   U[         R                  R!                  UR#                  U5      SS9/-  nM     U$ ! [         a  n[	        S5      UeSnAff = f)a  
Versatile (private) method defined for all TriInterpolators.

:meth:`_interpolate_multikeys` is a wrapper around method
:meth:`_interpolate_single_key` (to be defined in the child
subclasses).
:meth:`_interpolate_single_key actually performs the interpolation,
but only for 1-dimensional inputs and at valid locations (inside
unmasked triangles of the triangulation).

The purpose of :meth:`_interpolate_multikeys` is to implement the
following common tasks needed in all subclasses implementations:

- calculation of containing triangles
- dealing with more than one interpolation request at the same
  location (e.g., if the 2 derivatives are requested, it is
  unnecessary to compute the containing triangles twice)
- scaling according to self._unit_x, self._unit_y
- dealing with points outside of the grid (with fill value np.nan)
- dealing with multi-dimensional *x*, *y* arrays: flattening for
  :meth:`_interpolate_params` call and final reshaping.

(Note that np.vectorize could do most of those things very well for
you, but it does it by function evaluations over successive tuples of
the input arrays. Therefore, this tends to be more time-consuming than
using optimized numpy functions - e.g., np.dot - which can be used
easily on the flattened inputs, in the child-subclass methods
:meth:`_interpolate_single_key`.)

It is guaranteed that the calls to :meth:`_interpolate_single_key`
will be done with flattened (1-d) array-like input parameters *x*, *y*
and with flattened, valid `tri_index` arrays (no -1 index allowed).

Parameters
----------
x, y : array-like
    x and y coordinates where interpolated values are requested.
tri_index : array-like of int, optional
    Array of the containing triangle indices, same shape as
    *x* and *y*. Defaults to None. If None, these indices
    will be computed by a TriFinder instance.
    (Note: For point outside the grid, tri_index[ipt] shall be -1).
return_keys : tuple of keys from {'z', 'dzdx', 'dzdy'}
    Defines the interpolation arrays to return, and in which order.

Returns
-------
list of arrays
    Each array-like contains the expected interpolated values in the
    order defined by *return_keys* parameter.
dtypez'x and y shall have same shapes. Given: z and NzItri_index array is provided and shall have same shape as x and y. Given: r         r   dzdxdzdyz<return_keys items shall take values in {'z', 'dzdx', 'dzdy'}r   F)copy)r   r   float64r   r   ravelr   r   sizer   r   KeyErroremptynan_interpolate_single_keymamasked_invalidreshape)r   r   y	tri_indexreturn_keyssh_retx_scaledy_scaledsize_retmask_invalid_tri_indexvalid_xvalid_yret
return_keyreturn_indexerrscaleret_locs                      r   _interpolate_multikeys&TriInterpolator._interpolate_multikeysf   s3   n JJq

+JJq

+77agg (()yaggY@ A AHHQKHHQK\\>\\>778$ -I&( ; 'uVH67 7 +I???"'0O"ooi.@AO##%JD%&1=jI DLL"T\\/:<HE hhxrzz:G "GWH#;;W ?AF GGGBEE(()@u(MNNC! &$ 
  D  ": ;@CDDs   >	H//
I
9II
c                     [        S5      e)a  
Interpolate at points belonging to the triangulation
(inside an unmasked triangles).

Parameters
----------
return_key : {'z', 'dzdx', 'dzdy'}
    The requested values (z or its derivatives).
tri_index : 1D int array
    Valid triangle index (cannot be -1).
x, y : 1D arrays, same shape as `tri_index`
    Valid locations where interpolation is requested.

Returns
-------
1-d array
    Returned array of the same size as *tri_index*
zCTriInterpolator subclassesshould implement _interpolate_single_key!NotImplementedErrorr   rC   r8   r   r7   s        r   r3   'TriInterpolator._interpolate_single_key   s    & " #N O 	Or"   )r   r   r   r   r   r   N)Nr   )__name__
__module____qualname____firstlineno____doc__r    _docstring__call___docstringgradientrH   r3   __static_attributes__ r"   r   r   r      s1    ":$, 6:+1iVOr"   r   c                      ^  \ rS rSrSrSU 4S jjrS r\R                  \l        S r	\R                  \	l        S rSrU =r$ )	r      af  
Linear interpolator on a triangular grid.

Each triangle is represented by a plane so that an interpolated value at
point (x, y) lies on the plane of the triangle containing (x, y).
Interpolated values are therefore continuous across the triangulation, but
their first derivatives are discontinuous at edges between triangles.

Parameters
----------
triangulation : `~matplotlib.tri.Triangulation`
    The triangulation to interpolate over.
z : (npoints,) array-like
    Array of values, defined at grid points, to interpolate between.
trifinder : `~matplotlib.tri.TriFinder`, optional
    If this is not specified, the Triangulation's default TriFinder will
    be used by calling `.Triangulation.get_trifinder`.

Methods
-------
`__call__` (x, y) : Returns interpolated values at (x, y) points.
`gradient` (x, y) : Returns interpolated derivatives at (x, y) points.

c                 z   > [         TU ]  XU5        U R                  R                  U R                  5      U l        g rO   )superr    r   calculate_plane_coefficientsr   _plane_coefficients)r   r   r   r   	__class__s       r   r    LinearTriInterpolator.__init__  s4    95 <<TWWE 	 r"   c                 *    U R                  XS SS9S   $ NrP   r8   r9   r   rH   r   r   r7   s      r   __call__LinearTriInterpolator.__call__  +    **147= + ??@B 	Br"   c                 $    U R                  XS SS9$ N)r*   r+   rd   re   rf   s      r   gradientLinearTriInterpolator.gradient  #    **147G + I 	Ir"   c                    [         R                  " / SQUS9  US:X  a;  U R                  US4   U-  U R                  US4   U-  -   U R                  US4   -   $ US:X  a  U R                  US4   $ U R                  US4   $ )Nr)   rC   r   r   r'   r(   r*   )r   check_in_listr_   rM   s        r   r3   -LinearTriInterpolator._interpolate_single_key  s    0ZH,,Y\:1<,,Y\:1<=,,Y\:; < 6!++IqL99++IqL99r"   )r_   rO   )rQ   rR   rS   rT   rU   r    rg   r   rV   rl   rW   r3   rX   __classcell__r`   s   @r   r   r      sD    0FB '99HI '99H	: 	:r"   r   c                      ^  \ rS rSrSr  SU 4S jjrS r\R                  \l        S r	\R                  \	l        S rSS jr\S 5       r\S	 5       r\S
 5       rSrU =r$ )r	   i  a  
Cubic interpolator on a triangular grid.

In one-dimension - on a segment - a cubic interpolating function is
defined by the values of the function and its derivative at both ends.
This is almost the same in 2D inside a triangle, except that the values
of the function and its 2 derivatives have to be defined at each triangle
node.

The CubicTriInterpolator takes the value of the function at each node -
provided by the user - and internally computes the value of the
derivatives, resulting in a smooth interpolation.
(As a special feature, the user can also impose the value of the
derivatives at each node, but this is not supposed to be the common
usage.)

Parameters
----------
triangulation : `~matplotlib.tri.Triangulation`
    The triangulation to interpolate over.
z : (npoints,) array-like
    Array of values, defined at grid points, to interpolate between.
kind : {'min_E', 'geom', 'user'}, optional
    Choice of the smoothing algorithm, in order to compute
    the interpolant derivatives (defaults to 'min_E'):

    - if 'min_E': (default) The derivatives at each node is computed
      to minimize a bending energy.
    - if 'geom': The derivatives at each node is computed as a
      weighted average of relevant triangle normals. To be used for
      speed optimization (large grids).
    - if 'user': The user provides the argument *dz*, no computation
      is hence needed.

trifinder : `~matplotlib.tri.TriFinder`, optional
    If not specified, the Triangulation's default TriFinder will
    be used by calling `.Triangulation.get_trifinder`.
dz : tuple of array-likes (dzdx, dzdy), optional
    Used only if  *kind* ='user'. In this case *dz* must be provided as
    (dzdx, dzdy) where dzdx, dzdy are arrays of the same shape as *z* and
    are the interpolant first derivatives at the *triangulation* points.

Methods
-------
`__call__` (x, y) : Returns interpolated values at (x, y) points.
`gradient` (x, y) : Returns interpolated derivatives at (x, y) points.

Notes
-----
This note is a bit technical and details how the cubic interpolation is
computed.

The interpolation is based on a Clough-Tocher subdivision scheme of
the *triangulation* mesh (to make it clearer, each triangle of the
grid will be divided in 3 child-triangles, and on each child triangle
the interpolated function is a cubic polynomial of the 2 coordinates).
This technique originates from FEM (Finite Element Method) analysis;
the element used is a reduced Hsieh-Clough-Tocher (HCT)
element. Its shape functions are described in [1]_.
The assembled function is guaranteed to be C1-smooth, i.e. it is
continuous and its first derivatives are also continuous (this
is easy to show inside the triangles but is also true when crossing the
edges).

In the default case (*kind* ='min_E'), the interpolant minimizes a
curvature energy on the functional space generated by the HCT element
shape functions - with imposed values but arbitrary derivatives at each
node. The minimized functional is the integral of the so-called total
curvature (implementation based on an algorithm from [2]_ - PCG sparse
solver):

.. math::

    E(z) = \frac{1}{2} \int_{\Omega} \left(
        \left( \frac{\partial^2{z}}{\partial{x}^2} \right)^2 +
        \left( \frac{\partial^2{z}}{\partial{y}^2} \right)^2 +
        2\left( \frac{\partial^2{z}}{\partial{y}\partial{x}} \right)^2
    \right) dx\,dy

If the case *kind* ='geom' is chosen by the user, a simple geometric
approximation is used (weighted average of the triangle normal
vectors), which could improve speed on very large grids.

References
----------
.. [1] Michel Bernadou, Kamal Hassan, "Basis functions for general
    Hsieh-Clough-Tocher triangles, complete or reduced.",
    International Journal for Numerical Methods in Engineering,
    17(5):784 - 789. 2.01.
.. [2] C.T. Kelley, "Iterative Methods for Optimization".

c                   > [         TU ]  XU5        U R                  R                  5         [	        U R                  5      nUR                  5       u  pxpnXpl        Xl        US:g  nU R                  U   U R                  X   '   [        R                  " U5      U l        [        R                  " U	5      U l        [        R                  " XR                  -  XR                  -  /5      U l        U R                  U R                     U l        U R!                  U R                  5      U l        [$        R&                  " / SQUS9  U R)                  X5S9U l        [-        5       U l        g )Nr&   )usergeommin_E)kinddz)r]   r    r   get_cpp_triangulationr   _get_compressed_triangulation
_trianglesr   r   r   ptpr   r   column_stack_pts	_tris_pts_compute_tri_eccentricities_eccsr   rq   _compute_dof_dof_ReducedHCT_Element_ReferenceElement)r   r   r   rz   r   r|   tri_analyzercompressed_trianglescompressed_xcompressed_y	tri_renum
node_renum
valid_noder`   s                r   r    CubicTriInterpolator.__init__{  s(   95
 	113 #4#6#67#AAC		\	.# B&
*.''**=
&' vvl+vvl+OO\LL%@%1LL%@%B C	 4??355dnnE
44@%%d%2	!4!6r"   c                 *    U R                  XS SS9S   $ rc   re   rf   s      r   rg   CubicTriInterpolator.__call__  ri   r"   c                 $    U R                  XS SS9$ rk   re   rf   s      r   rl   CubicTriInterpolator.gradient  rn   r"   c                    [         R                  " / SQUS9  U R                  U   nU R                  X4U5      nU R                  U   n[
        R                  " U R                  U   SS9nUS:X  a  U R                  R                  XgU5      $ U R                  U5      n	U R                  R                  XiXx5      n
US:X  a
  U
S S 2SS4   $ U
S S 2SS4   $ )Nr)   rp   r'   axisr   r*   r   )r   rq   r   _get_alpha_vecr   r   expand_dimsr   r   get_function_values_get_jacobianget_function_derivatives)r   rC   r8   r   r7   tris_ptsalphaeccdofJr*   s              r   r3   ,CubicTriInterpolator._interpolate_single_key  s    0ZH>>),##A(3jj#nnTYYy1:))==C! ! ""8,A))BB#$DV#Aq!G}$Aq!G}$r"   c                     US:X  a'  Uc  [        S5      e[        XS9nUR	                  5       $ US:X  a  [        U 5      nUR	                  5       $ [        U 5      nUR	                  5       $ )a  
Compute and return nodal dofs according to kind.

Parameters
----------
kind : {'min_E', 'geom', 'user'}
    Choice of the _DOF_estimator subclass to estimate the gradient.
dz : tuple of array-likes (dzdx, dzdy), optional
    Used only if *kind*=user; in this case passed to the
    :class:`_DOF_estimator_user`.

Returns
-------
array-like, shape (npts, 2)
    Estimation of the gradient at triangulation nodes (stored as
    degree of freedoms of reduced-HCT triangle elements).
rw   zQFor a CubicTriInterpolator with *kind*='user', a valid *dz* argument is expected.r{   rx   )r   _DOF_estimator_user_DOF_estimator_geom_DOF_estimator_min_Ecompute_dof_from_df)r   rz   r|   TEs       r   r   !CubicTriInterpolator._compute_dof  s~    $ 6>z  "9 : : %T1B
 %%''	 V^$T*B %%'' &d+B%%''r"   c                    UR                   S-
  nUSS2SSS24   USS2SSS24   -
  nUSS2SSS24   USS2SSS24   -
  n[        R                  " XE/SS9n[        U5      n[        R                  " X/SS9USS2SSS24   -
  nXv-  n	[	        U	5      n
U[        [        R
                  " X5      5      -  nX-  n[        SUSS2SS4   -
  USS2SS4   -
  /USS2SS4   /USS2SS4   //5      nU$ )a  
Fast (vectorized) function to compute barycentric coordinates alpha.

Parameters
----------
x, y : array-like of dim 1 (shape (nx,))
    Coordinates of the points whose points barycentric coordinates are
    requested.
tris_pts : array like of dim 3 (shape: (nx, 3, 2))
    Coordinates of the containing triangles apexes.

Returns
-------
array of dim 2 (shape (nx, 3))
    Barycentric coordinates of the points inside the containing
    triangles.
r(   Nr'   r   r&   r   )ndimr   stack_transpose_vectorized_pseudo_inv22sym_vectorizedr   _to_matrix_vectorized)r   r7   r   r   ababTabOMmetric
metric_invCovarksir   s                 r   r   #CubicTriInterpolator._get_alpha_vec  s   & }}QQ1WAq 11Q1WAq 11hhvB'"3'XXqf1%Aq(99
 18
*2>>"+CDD %s1a7|^C1aL()C1aL>C1aL>'K Lr"   c                    [         R                  " U SS2SSS24   U SS2SSS24   -
  5      n[         R                  " U SS2SSS24   U SS2SSS24   -
  5      n[        USS2S4   USS2S4   /USS2S4   USS2S4   //5      nU$ )a[  
Fast (vectorized) function to compute triangle jacobian matrix.

Parameters
----------
tris_pts : array like of dim 3 (shape: (nx, 3, 2))
    Coordinates of the containing triangles apexes.

Returns
-------
array of dim 3 (shape (nx, 2, 2))
    Barycentric coordinates of the points inside the containing
    triangles.
    J[itri, :, :] is the jacobian matrix at apex 0 of the triangle
    itri, so that the following (matrix) relationship holds:
       [dz/dksi] = [J] x [dz/dx]
    with x: global coordinates
         ksi: element parametric coordinates in triangle first apex
         local basis.
Nr'   r   r(   )r   arrayr   )r   r   r   r   s       r   r   "CubicTriInterpolator._get_jacobian  s    , HHXaAg&!Q')::;HHXaAg&!Q')::;!AadGQq!tW#5$%adGQq!tW#5#7 8r"   c                    [         R                  " U SS2SSS24   U SS2SSS24   -
  SS9n[         R                  " U SS2SSS24   U SS2SSS24   -
  SS9n[         R                  " U SS2SSS24   U SS2SSS24   -
  SS9n[        U5      U-  SS2SS4   n[        U5      U-  SS2SS4   n[        U5      U-  SS2SS4   n[        Xe-
  U-  /XF-
  U-  /XT-
  U-  //5      $ )a   
Compute triangle eccentricities.

Parameters
----------
tris_pts : array like of dim 3 (shape: (nx, 3, 2))
    Coordinates of the triangles apexes.

Returns
-------
array like of dim 2 (shape: (nx, 3))
    The so-called eccentricity parameters [1] needed for HCT triangular
    element.
Nr(   r'   r   r   )r   r   r   r   )r   r   r   cdot_adot_bdot_cs          r   r   0CubicTriInterpolator._compute_tri_eccentricities!  s     NN8Aq!G,x1a/@@qINN8Aq!G,x1a/@@qINN8Aq!G,x1a/@@qI 'q)A-q!Qw7&q)A-q!Qw7&q)A-q!Qw7 %u'<&=(-u'<&=(-u'<&=&? @ 	@r"   )	r   r   r   r   r   r   r   r   r   )ry   NNrO   )rQ   rR   rS   rT   rU   r    rg   r   rV   rl   rW   r3   r   staticmethodr   r   r   rX   rs   rt   s   @r   r	   r	     s    [x BF'7RB '99HI '99H%$(< $ $L  6 @ @r"   r	   c                      \ rS rSrSr\R                  " / SQ/ SQ/ SQ/ SQ/ SQ/ SQ/ S	Q/ S
Q/ SQ/	5      r\R                  " / SQ/ SQ/ SQ/ SQ/ SQ/ SQ/ SQ/ SQ/ SQ/	5      r\R                  " / SQ/ SQ/ SQ/ SQ/ SQ/ SQ/ SQ/ SQ/ SQ/	5      r	\R                  " / SQ/ SQ/ SQ/ SQ/ SQ/ SQ/ SQ/ SQ/ SQ/	5      r
\R                  " SS/SS/SS/SS/SS/SS//5      r\R                  " / SQ/ SQ/ SQ/ SQ/ SQ/ S Q/ SQ/ SQ/ S!Q/	5      rS"r\R                  " / S#Q/ S$Q/ S%Q/ S&Q/ S'Q/ S(Q/ S)Q/ S*Q/ S+Q/	\R                  S,9r\R                   " S"/\R                  S,9S--  r\R                  " / SQ/ SQ/ S.Q/5      r\R                  " SS/SS//5      r\R                  " SS/SS//5      rS/ rS0 rS1 rS2 rS3 rS8S4 jrS5 rS6rg7)9r   iB  a  
Implementation of reduced HCT triangular element with explicit shape
functions.

Computes z, dz, d2z and the element stiffness matrix for bending energy:
E(f) = integral( (d2z/dx2 + d2z/dy2)**2 dA)

*** Reference for the shape functions: ***
[1] Basis functions for general Hsieh-Clough-Tocher _triangles, complete or
    reduced.
    Michel Bernadou, Kamal Hassan
    International Journal for Numerical Methods in Engineering.
    17(5):784 - 789.  2.01

*** Element description: ***
9 dofs: z and dz given at 3 apex
C1 (conform)

)
        r   r         @r   r   r   r   r   r   )
      пr   r         ?      ?r   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   )
r   r   r         r         @r   r   r   r   )
r   r   r   r         ?r   r   r   r   r   )
r   r   r         r   r   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   )
      r   r         ?r   r   r   r   r         )
r   r   r         ?r   r   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   )
r   r   r         r   r   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r          r   )r   r   r   	   )qq?qq?qq?)r   r   r   )98?r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   r   r   r$   g      "@)r   r          @c                 P   [         R                  " USS9SS2S4   n[        X* SS9n[        X$* SS9nUSS2SS4   nUSS2SS4   nUSS2SS4   n	Xw-  n
X-  nX-  n[        X-  /X-  /X-  /X-  /X-  /X-  /X-  /X-  /X-  /Xx-  U	-  //
5      nU R                  U-  nU[        USS2SS4   U R                  U-  5      -  nU[        USS2SS4   U R                  U-  5      -  nU[        USS2SS4   U R                  U-  5      -  n[        USU-  SS9nX?-  SS2SS4   $ )a_  
Parameters
----------
alpha : is a (N x 3 x 1) array (array of column-matrices) of
barycentric coordinates,
ecc : is a (N x 3 x 1) array (array of column-matrices) of triangle
eccentricities,
dofs : is a (N x 1 x 9) arrays (arrays of row-matrices) of computed
degrees of freedom.

Returns
-------
Returns the N-array of interpolated function values.
r'   r   Nr   r(      )	r   argmin_roll_vectorizedr   M_scalar_vectorizedM0M1M2)r   r   r   dofssubtrir   Er   r7   r   x_sqy_sqz_sqVprodss                   r   r   '_ReducedHCT_Element.get_function_values  sl    5q)!Q$/ugA6S'21aL1aL1aLsss!VHtvh46(TVHtvhVHtvh13q5'#3 4 vvz"1Q1W:tww{;;"1Q1W:tww{;;"1Q1W:tww{;;T1V8!4!Q'""r"   c                 @   [         R                  " USS9SS2S4   n[        X* SS9n[        X5* SS9nUSS2SS4   nUSS2SS4   n	USS2SS4   n
X-  nX-  nX-  n[        SU-  SU-  /SU-  S/SSU-  /S	U-  U
-  S	U-  U
-  U-   /S	U-  U	-  U-   S	U-  U	-  /S
U-  U	-  U-
  U* /S
U	-  U
-  U/US
U	-  U
-  /U* S
U-  U
-  U-
  /X-  X-  -
  X-  X-  -
  //
5      nU[	        U R
                  USSS9-  nU R                  U-  nU[        USS2SS4   U R                  U-  5      -  nU[        USS2SS4   U R                  U-  5      -  nU[        USS2SS4   U R                  U-  5      -  n[        USU-  SS9nUU-  n[        U5      nU[        U5      -  nU$ )a  
Parameters
----------
*alpha* is a (N x 3 x 1) array (array of column-matrices of
barycentric coordinates)
*J* is a (N x 2 x 2) array of jacobian matrices (jacobian matrix at
triangle first apex)
*ecc* is a (N x 3 x 1) array (array of column-matrices of triangle
eccentricities)
*dofs* is a (N x 1 x 9) arrays (arrays of row-matrices) of computed
degrees of freedom.

Returns
-------
Returns the values of interpolated function derivatives [dz/dx, dz/dy]
in global coordinates at locations alpha, as a column-matrices of
shape (N x 2 x 1).
r'   r   Nr   r(   r   r   r   r   r   
block_sizer   r   )r   r   r   r   _extract_submatrices	rotate_dVr   r   r   r   r   _safe_inv22_vectorizedr   )r   r   r   r   r   r   r   r   r   r7   r   r   r   r   dVr   dsdksidfdksiJ_invdfdxs                       r   r   ,_ReducedHCT_Element.get_function_derivatives  s&   & 5q)!Q$/ugA6S'21aL1aL1aLsss"Ts4x(T'R(4(a%'3q574<(U1WT\Aa(d1fTk4%(a464(Aa(EBqDF4K(#ac'AC(
$* 
+ &NNFqq: : vv{"1Q1W:tww|<<"1Q1W:tww|<<"1Q1W:tww|<<!$&q9 'q),V44r"   c                 l    U R                  X5      nXE-  nU R                  U5      nXg-  n[        U5      $ )a/  
Parameters
----------
*alpha* is a (N x 3 x 1) array (array of column-matrices) of
barycentric coordinates
*J* is a (N x 2 x 2) array of jacobian matrices (jacobian matrix at
triangle first apex)
*ecc* is a (N x 3 x 1) array (array of column-matrices) of triangle
eccentricities
*dofs* is a (N x 1 x 9) arrays (arrays of row-matrices) of computed
degrees of freedom.

Returns
-------
Returns the values of interpolated function 2nd-derivatives
[d2z/dx2, d2z/dy2, d2z/dxdy] in global coordinates at locations alpha,
as a column-matrices of shape (N x 3 x 1).
)get_d2Sidksij2get_Hrot_from_Jr   )	r   r   r   r   r   d2sdksi2d2fdksi2H_rotd2fdx2s	            r   get_function_hessians)_ReducedHCT_Element.get_function_hessians  s>    & &&u2?$$Q'!$V,,r"   c                     [         R                  " USS9SS2S4   n[        X* SS9n[        X#* SS9nUSS2SS4   nUSS2SS4   nUSS2SS4   n[        SU-  SU-  SU-  /SU-  SS/SSU-  S/SU-  SU-  S	U-  -
  SU-  SU-  -
  /SU-  S	U-  -
  SU-  SU-  SU-  -
  /SU-  S	U-  -
  SS
U-  /SU-  SSU-  /SSU-  SU-  /SSU-  S	U-  -
  S
U-  /S
U-  S
U-  Xg-
  U-
  //
5      n	U	[	        U R
                  USSS9-  n	U R                  U	-  n
U
[        USS2SS4   U R                  U	-  5      -  n
U
[        USS2SS4   U R                  U	-  5      -  n
U
[        USS2SS4   U R                  U	-  5      -  n
[        U
SU-  SS9nU$ )aK  
Parameters
----------
*alpha* is a (N x 3 x 1) array (array of column-matrices) of
barycentric coordinates
*ecc* is a (N x 3 x 1) array (array of column-matrices) of triangle
eccentricities

Returns
-------
Returns the arrays d2sdksi2 (N x 3 x 1) Hessian of shape functions
expressed in covariant coordinates in first apex basis.
r'   r   Nr   r(   g      @r   r   g      @r   r   r   )r   r   r   r   r   
rotate_d2Vr   r   r   r   r   )r   r   r   r   r   r   r   r7   r   d2Vr   r   s               r   r   "_ReducedHCT_Element.get_d2Sidksij2  s    5q)!Q$/ugA6S'21aL1aL1aL#Q$RT1-Q$r"-RT"-Q$1RT	2a419-T"Q$YRT2a419-T"Q$Yrs1u-Q$r1-RT1-1RT	s1u-QCEqs1u-
%/ 
0 (OOV; ;vv|"1Q1W:tww}=="1Q1W:tww}=="1Q1W:tww}==#D!F(;r"   c                 L   [         R                  " US5      nU R                  U-  nU R                  U-  n[         R                  " USS/[         R
                  S9nSUSS2SS4'   SUSS2SS4'   SUSS2SS4'   XSS2SS2SS24'   XFSS2SS2SS24'   XVSS2S	S2S	S24'   U R                  US
S9u  px[         R                  " USS/[         R
                  S9n	U R                  n
U R                  n[        U R                  5       H  n[         R                  " XSS24   U5      R                  US5      n[         R                  " US5      nX   nU R                  X5      nX-  nXUU R                  -  [!        U5      -  -  -  n	M     [!        U5      U	-  U-  n	[#        X5      $ )a  
Parameters
----------
*J* is a (N x 2 x 2) array of jacobian matrices (jacobian matrix at
triangle first apex)
*ecc* is a (N x 3 x 1) array (array of column-matrices) of triangle
eccentricities

Returns
-------
Returns the element K matrices for bending energy expressed in
GLOBAL nodal coordinates.
K_ij = integral [ (d2zi/dx2 + d2zi/dy2) * (d2zj/dx2 + d2zj/dy2) dA]
tri_J is needed to rotate dofs from local basis to global basis
r   r   r$   r'   Nr            T)return_arear(   )r   r/   J0_to_J1J0_to_J2zerosr-   r   gauss_w	gauss_ptsrangen_gausstiler6   r   r   r   r   r   )r   r   r   nJ1J2DOF_rotr   areaKweightsptsigaussr   weight	d2Skdksi2d2Skdx2s                    r   get_bending_matrices(_ReducedHCT_Element.get_bending_matrices>  s     GGCO ]]Q]]Q((Aq!9BJJ71a1a1a 1Q3!!1Q3!!1Q3! **1$*? HHaAYbjj1,,nnDLL)FGGC	NA.66q!<ENN5!,E_F++E7I'G7TVV+.CG.LLMMA * "'*Q.8 "$**r"   c           	      H   [        U5      nUSS2SS4   nUSS2SS4   nUSS2SS4   nUSS2SS4   n[        XD-  Xf-  XF-  /Xw-  XU-  Xu-  /SU-  U-  SU-  U-  XE-  Xg-  -   //5      nU(       d  U$ SUSS2SS4   USS2SS4   -  USS2SS4   USS2SS4   -  -
  -  n	X4$ )a#  
Parameters
----------
*J* is a (N x 2 x 2) array of jacobian matrices (jacobian matrix at
triangle first apex)

Returns
-------
Returns H_rot used to rotate Hessian from local basis of first apex,
to global coordinates.
if *return_area* is True, returns also the triangle area (0.5*det(J))
Nr   r'   r(   r   )r   r   )
r   r   r  r   Ji00Ji11Ji10Ji01r   r  s
             r   r   #_ReducedHCT_Element.get_Hrot_from_Jq  s     'q)Q1W~Q1W~Q1W~Q1W~%Y	49-Y	49-tVD[!D&+ty':;'= > L!Aq!G*Qq!QwZ/!Aq!G*Qq!QwZ2GGHD;r"   c                 p   [         R                  " US5      n[         R                  " U[         R                  S9n[         R                  " US[         R                  S9n/ SQn/ SQn	[        XsSS2S4   S-  USS2S4   S-  S-   XsSS2S4   S-  USS2S4   S-  S-   XsSS2S4   S-  USS2S4   S-  S-   /	/5      n
[         R                  " US	S/[         R                  S9n[        X-  5      nX-  nU R                  X5      n[         R                  " U[         R                  " XhU5         5      n[         R                  " U[         R                  " XhU5         5      n[         R                  " U[         R                  " XhU5         5      nU[         R                  " XhU	5         n[         R                  " USS
9nUU-  SS2SS2S4   * nU
[         R                  " US/U5         SS2SSS24   n[         R                  " [         R                  " U5      [         R                  " U5      S9nUUUU4$ )a  
Build K and F for the following elliptic formulation:
minimization of curvature energy with value of function at node
imposed and derivatives 'free'.

Build the global Kff matrix in cco format.
Build the full Ff vec Ff = - Kfc x Uc.

Parameters
----------
*J* is a (N x 2 x 2) array of jacobian matrices (jacobian matrix at
triangle first apex)
*ecc* is a (N x 3 x 1) array (array of column-matrices) of triangle
eccentricities
*triangles* is a (N x 3) array of nodes indexes.
*Uc* is (N x 3) array of imposed displacements at nodes

Returns
-------
(Kff_rows, Kff_cols, Kff_vals) Kff matrix in coo format - Duplicate
(row, col) entries must be summed.
Ff: force vector - dim npts * 3
r   r$   r&   )r'   r(   r	     r
     )r   r   r  Nr(   r'   r   r   r  )r   r/   arangeint32fullr   onesr   r   r.   ix_r   bincount)r   r   r   	trianglesUcntri	vec_range	c_indicesf_dofc_doff_dof_indicesexpand_indicesf_row_indicesf_col_indicesK_elemKff_valsKff_rowsKff_colsKfc_elemUc_elemFf_elem
Ff_indicesFfs                          r   get_Kff_and_Ff"_ReducedHCT_Element.get_Kff_and_Ff  s   0 wwsAIId"((3	GGD"BHH5	" .Aq()AqD/!*;A*=Aq()AqD/!*;A*=Aq()AqD/!*;A*=0? /@ A
 $1RXX>-n.LM&6**12 88F266)E#BCD88M"&&5*IJK88M"&&5*IJK "&&59:..!,w&1a00"266)aS%#@A!Q'J
 [[*-rxx7HI8R//r"   rY   N)F)rQ   rR   rS   rT   rU   r   r   r   r   r   r   r   r  r  r-   r  r/  r  r   r  r  r   r   r  r   r   r   rF  rX   rY   r"   r   r   r   B  s	   * 	GGGGGGGGG	I 		JA 
HHHHHHHHH	J 	
KB 
FFFFFFFFF	H 	
IB 
FFFFFFFFF	H 	
IB B*Rj*sCj*Rj2 3I <''H IJ G5555555557 ?AjjJI ggqc,r1G 	,l;<A xx#cBZ01Hxx2sr3Z01H #D6p-2'R1+f<C0r"   r   c                   :    \ rS rSrSrS rS rS r\S 5       r	Sr
g)	_DOF_estimatori  aP  
Abstract base class for classes used to estimate a function's first
derivatives, and deduce the dofs for a CubicTriInterpolator using a
reduced HCT element formulation.

Derived classes implement ``compute_df(self, **kwargs)``, returning
``np.vstack([dfx, dfy]).T`` where ``dfx, dfy`` are the estimation of the 2
gradient coordinates.
c                 R   [         R                  " [        US9  UR                  U l        UR                  U l        UR
                  U l        UR                  U l        UR                  UR                  sU l        U l	        U R                  " S0 UD6U l        U R                  5         g )N)interpolatorrY   )r   r   r	   r   r   r   r   r   r   r   
compute_dzr|   r   )r   rK  kwargss      r   r    _DOF_estimator.__init__  s    2N %%	%//&11(4(<(<(4(<(< 	%t|//+F+  "r"   c                     [         erO   rK   )r   rM  s     r   rL  _DOF_estimator.compute_dz  s    !!r"   c                     [         R                  U R                  5      nU R                  U R                     nU R
                  U R                     nU R                  X#U5      nU$ )zE
Compute reduced-HCT elements degrees of freedom, from the gradient.
)r	   r   r   r   r   r|   get_dof_vec)r   r   tri_ztri_dztri_dofs        r   r   "_DOF_estimator.compute_dof_from_df  sS     !..t~~>t')""5!4r"   c           	      n   U R                   S   n[        R                  " US/[        R                  S9n[        R
                  U-  n[        R                  U-  nU[        R                  " USS2SSS24   SS9-  nU[        R                  " USS2SSS24   SS9-  nU[        R                  " USS2SSS24   SS9-  n	[        USS2SS4   USS2SS4   U	SS2SS4   /USS2SS4   USS2SS4   U	SS2SS4   //5      n
XSS2SSS	24'   U
SS2S4   USS2SS
S	24'   U
SS2S4   USS2SSS	24'   U$ )a  
Compute the dof vector of a triangle, from the value of f, df and
of the local Jacobian at each node.

Parameters
----------
tri_z : shape (3,) array
    f nodal values.
tri_dz : shape (3, 2) array
    df/dx, df/dy nodal values.
J
    Jacobian matrix in local basis of apex 0.

Returns
-------
dof : shape (9,) array
    For each apex ``iapex``::

        dof[iapex*3+0] = f(Ai)
        dof[iapex*3+1] = df(Ai).(AiAi+)
        dof[iapex*3+2] = df(Ai).(AiAi-)
r   r   r$   Nr(   r   r'   r
  r   r*  )	r   r   r  r-   r   r  r  r   r   )rS  rT  r   nptr   r  r  col0col1col2r   s              r   rR  _DOF_estimator.get_dof_vec  sS   0 kk!nhhQxrzz2 ))A- ))A-2>>&Aq/::BNN6!Q'?;;BNN6!Q'?;;&!Q']DAqM41a=9!Q']DAqM41a=9(; < Aq1uHq!tAq1uHq!tAq1uH
r"   )r   r   r   r   r   r|   r   N)rQ   rR   rS   rT   rU   r    rL  r   r   rR  rX   rY   r"   r   rI  rI    s*    	#" & &r"   rI  c                       \ rS rSrSrS rSrg)r   i%  z3dz is imposed by user; accounts for scaling if any.c                     Uu  p#X R                   -  nX0R                  -  n[        R                  " X#/5      R                  $ rO   )r   r   r   vstackT)r   r|   r*   r+   s       r   rL  _DOF_estimator_user.compute_dz(  s8    ll"ll"yy$&(((r"   rY   N)rQ   rR   rS   rT   rU   rL  rX   rY   r"   r   r   r   %  s
    =)r"   r   c                   *    \ rS rSrSrS rS rS rSrg)r   i/  z=Fast 'geometric' approximation, recommended for large arrays.c                 "   U R                  5       nU R                  5       n[        R                  " [        R                  " U R
                  5      [        R                  " U5      S9n[        R                  " U5      n[        R                  " U5      n[        S5       H7  nUSS2U4   USS2S4   -  USS2U4'   USS2U4   USS2S4   -  USS2U4'   M9     [        R                  " [        R                  " U R
                  5      [        R                  " U5      S9n[        R                  " [        R                  " U R
                  5      [        R                  " U5      S9nXs-  n	X-  n
[        R                  " X/5      R                  $ )a  
self.df is computed as weighted average of _triangles sharing a common
node. On each triangle itri f is first assumed linear (= ~f), which
allows to compute d~f[itri]
Then the following approximation of df nodal values is then proposed:
    f[ipt] = SUM ( w[itri] x d~f[itri] , for itri sharing apex ipt)
The weighted coeff. w[itri] are proportional to the angle of the
triangle itri at apex ipt
r+  r   Nr   r'   )
compute_geom_weightscompute_geom_gradsr   r1  r.   r   
empty_liker  r_  r`  )r   	el_geom_wel_geom_grad
w_node_sumdfx_el_wdfy_el_wiapexdfx_node_sumdfy_node_sum	dfx_estim	dfy_estims              r   rL  _DOF_estimator_geom.compute_dz2  s?    --/	..0 [[$//!:)+))<>
 ==+==+1XE!*1e8!4\!Q$5G!GHQX!*1e8!4\!Q$5G!GHQX  {{288DOO#<+-88H+=?{{288DOO#<+-88H+=? !+	 +	yy)/0222r"   c                    [         R                  " [         R                  " U R                  S5      S/5      nU R                  n[        S5       H  nUSS2US-  SS24   nUSS2US-   S-  SS24   nUSS2US-
  S-  SS24   n[         R                  " USS2S4   USS2S4   -
  USS2S4   USS2S4   -
  5      n[         R                  " USS2S4   USS2S4   -
  USS2S4   USS2S4   -
  5      n[         R                  " X-
  [         R                  -  S-  5      n	S[         R                  " U	S-
  5      -
  USS2U4'   M     U$ )z|
Build the (nelems, 3) weights coeffs of _triangles angles,
renormalized so that np.sum(weights, axis=1) == np.ones(nelems)
r   r   Nr'   r   )	r   r  r/   r   r   r  arctan2abspi)
r   r  r   iptp0p1p2alpha1alpha2angles
             r   rd  (_DOF_estimator_geom.compute_geom_weightsS  s?   
 ((BGGDOOQ7;<>>8C!S1Wa-(B!c!eq[!+,B!c!eq[!+,BZZ1a4AqD 12ad8Bq!tH3DEFZZ1a4AqD 12ad8Bq!tH3DEF FFV]bee3q89E "BFF59$55GAsFO  r"   c                 r   U R                   nU R                  U R                     nUSS2SSS24   USS2SSS24   -
  nUSS2SSS24   USS2SSS24   -
  n[        R                  " X4/5      n[        U5      nUSS2S4   USS2S4   -
  nUSS2S4   USS2S4   -
  n[        R                  " Xx/5      R                  n	[        R                  " U	5      n
U	SS2S4   USS2SS4   -  U	SS2S4   USS2SS4   -  -   U
SS2S4'   U	SS2S4   USS2SS4   -  U	SS2S4   USS2SS4   -  -   U
SS2S4'   U
$ )z
Compute the (global) gradient component of f assumed linear (~f).
returns array df of shape (nelems, 2)
df[ielem].dM[ielem] = dz[ielem] i.e. df = dz x dM = dM.T^-1 x dz
Nr'   r   r(   )	r   r   r   r   dstackr   r_  r`  rf  )r   r   tris_fdM1dM2dMdM_invdZ1dZ2dZdfs              r   re  &_DOF_estimator_geom.compute_geom_gradsi  sZ    >>(q!Qw(1a7"33q!Qw(1a7"33YYz" (+QTlVAqD\)QTlVAqD\)YYz"$$]]2 ad8F1a7O+bAhvaAg.FF1a4ad8F1a7O+bAhvaAg.FF1a4	r"   rY   N)	rQ   rR   rS   rT   rU   rL  rd  re  rX   rY   r"   r   r   r   /  s    G3B,r"   r   c                   8   ^  \ rS rSrSrU 4S jrU 4S jrSrU =r$ )r   i  z
The 'smoothest' approximation, df is computed through global minimization
of the bending energy:
  E(f) = integral[(d2z/dx2 + d2z/dy2 + 2 d2z/dxdy)**2 dA]
c                 F   > UR                   U l         [        TU ]	  U5        g rO   )r   r]   r    )r   Interpolatorr`   s     r   r    _DOF_estimator_min_E.__init__  s    !''
&r"   c                   > [         TU ]  5       n[        R                  " U5      n[	        5       n[
        R                  U R                  5      nU R                  nU R                  nU R                  U R                     nUR                  XEXg5      u  ppSnUR                  S   n[        XU	X4S9nUR                  5         [        XX,S9u  nn[        R                   R#                  UR%                  U5      U-
  5      nUU:  a  [&        R(                  " S5        Un[        R*                  " U R,                  R                  S   S/[        R.                  S9nUSSS2   USS2S4'   US	SS2   USS2S	4'   U$ )
zc
Elliptic solver for bending energy minimization.
Uses a dedicated 'toy' sparse Jacobi PCG solver.
绽|=r   )r   )Ar   x0tolzIn TriCubicInterpolator initialization, PCG sparse solver did not converge after 1000 iterations. `geom` approximation is used instead of `min_E`r(   r$   Nr'   )r]   rL  r   r.   r   r	   r   r   r   r   r   rF  r   _Sparse_Matrix_coocompress_csc_cglinalgnormdotr   warn_externalr1   r   r-   )r   dz_initUf0reference_elementr   eccsr2  r3  r?  r@  r>  rE  r  n_dofKff_cooUfrE   err0r|   r`   s                      r   rL  _DOF_estimator_min_E.compute_dz  s\    '$&hhw/1 ..t~~>zzOO	VVDOO$ ,=+K+KY,$(H $X,1>;#7C yy~~gkk#.34#:  9 : B XXtyyq)1-RZZ@cc71a4add81a4	r"   )r   )	rQ   rR   rS   rT   rU   r    rL  rX   rs   rt   s   @r   r   r     s    
', ,r"   r   c                   H    \ rS rSrS rS rS rS rS rS r	\
S 5       rS	rg
)r  i  c                    Uu  U l         U l        [        R                  " U[        R                  S9U l        [        R                  " U[        R                  S9U l        [        R                  " U[        R                  S9U l        g)a  
Create a sparse matrix in coo format.
*vals*: arrays of values of non-null entries of the matrix
*rows*: int arrays of rows of non-null entries of the matrix
*cols*: int arrays of cols of non-null entries of the matrix
*shape*: 2-tuple (n, m) of matrix shape
r$   N)	r  mr   r   r-   valsr-  rowscols)r   r  r  r  r   s        r   r    _Sparse_Matrix_coo.__init__  sS     JJt2::6	JJt2884	JJt2884	r"   c                     UR                   U R                  4:X  d   e[        R                  " U R                  U R
                  XR                     -  U R                  S9$ )zj
Dot product of self by a vector *V* in sparse-dense to dense format
*V* dense vector of shape (self.m,).
)r  	minlength)r   r  r   r1  r  r  r  )r   r   s     r   r  _Sparse_Matrix_coo.dot  sL    
 ww466)###{{499#'99Qyy\#9%)VV- 	-r"   c                    [         R                  " U R                  U R                  U R                  -  -   SSS9u  pnU R                  U   U l        U R                  U   U l        [         R
                  " X0R                  S9U l        g)zF
Compress rows, cols, vals / summing duplicates. Sort for csc format.
TrD   return_inverser+  N)r   uniquer  r  r  r1  r  r   _r  indicess       r   r  _Sparse_Matrix_coo.compress_csc  sk      YYIItyy((d47 IIf%	IIf%	KK;	r"   c                    [         R                  " U R                  U R                  -  U R                  -   SSS9u  pnU R                  U   U l        U R                  U   U l        [         R
                  " X0R                  S9U l        g)zF
Compress rows, cols, vals / summing duplicates. Sort for csr format.
Tr  r+  N)r   r  r  r  r  r1  r  r  s       r   compress_csr_Sparse_Matrix_coo.compress_csr  sk      YYFF499tyy(d47 IIf%	IIf%	KK;	r"   c                 2   [         R                  " U R                  U R                  /[         R                  S9nU R
                  R                  n[        U5       H8  nXR                  U   U R                  U   4==   U R
                  U   -  ss'   M:     U$ )zI
Return a dense matrix representing self, mainly for debugging purposes.
r$   )
r   r  r  r  r-   r  r/   r  r  r  )r   rB   nvalsis       r   to_dense_Sparse_Matrix_coo.to_dense  sp     hh'rzz:		uA		!diil*+tyy|;+ 
r"   c                 >    U R                  5       R                  5       $ rO   )r  __str__)r   s    r   r  _Sparse_Matrix_coo.__str__  s    }}&&((r"   c                     U R                   U R                  :H  n[        R                  " [	        U R
                  U R
                  5      [        R                  S9nU R                  U   X R                   U   '   U$ )z3Return the (dense) vector of the diagonal elements.r$   )r  r  r   r  minr  r-   r  )r   in_diagdiags      r   r  _Sparse_Matrix_coo.diag  sX     99		)xxDFFDFF+2::>#'99W#5YYw r"   )r  r  r  r  r  N)rQ   rR   rS   rT   r    r  r  r  r  r  propertyr  rX   rY   r"   r   r  r    s4    5-	<	<)  r"   r  c                    UR                   nU R                  U:X  d   eU R                  U:X  d   e[        R                  R                  U5      nU R                  n[        R                  " US5      nUc  [        R                  " U5      nOUnXR                  U5      -
  n	X-  n
[        R                  " U5      nSn[        R                  " X5      nSn[        R                  " [        U5      5      X6-  :  a  X:  a  XU-  -   nU R                  U5      nU[        R                  " X5      -  nU	UU-  -
  n	X-  n
Un[        R                  " X5      nUUU-  -   nUU-  nUS-  n[        R                  " [        U5      5      X6-  :  a  X:  a  M  [        R                  R                  U R                  U5      U-
  5      nUU4$ )a8  
Use Preconditioned Conjugate Gradient iteration to solve A x = b
A simple Jacobi (diagonal) preconditioner is used.

Parameters
----------
A : _Sparse_Matrix_coo
    *A* must have been compressed before by compress_csc or
    compress_csr method.
b : array
    Right hand side of the linear system.
x0 : array, optional
    Starting guess for the solution. Defaults to the zero vector.
tol : float, optional
    Tolerance to achieve. The algorithm terminates when the relative
    residual is below tol. Default is 1e-10.
maxiter : int, optional
    Maximum number of iterations.  Iteration will stop after *maxiter*
    steps even if the specified tolerance has not been achieved. Defaults
    to 1000.

Returns
-------
x : array
    The converged solution.
err : float
    The absolute error np.linalg.norm(A.dot(x) - b)
gư>r   r   r'   )r/   r  r  r   r  r  r  maximumr  r  sqrtrt  )r  r   r  r  maxiterr  b_normkvecr   rwpbetarhokr   r   rhooldrE   s                      r   r  r    s}   : 	
A33!8O833!8O8YY^^AF 66D::dD!D 
zHHQK	EE!HA	A
AD
&&,C	A 773s8sz)QJEE!HBFF1L aKFffQlaK6z	Q 773s8sz) ))..qA
&Cc6Mr"   c                 Z   [         R                  " SU S9  [        R                  " U 5      nU SS2SS4   U SS2SS4   -  nX SS2SS4   U SS2SS4   -  -
  n[        R                  " U5      S[        R                  " U5      -  :  n[        R
                  " U5      (       a  SU-  nO,[        R                  " U R                  S   5      nSX4   -  XT'   U SS2SS4   U-  USS2SS4'   U SS2SS4   * U-  USS2SS4'   U SS2SS4   * U-  USS2SS4'   U SS2SS4   U-  USS2SS4'   U$ )z
Inversion of arrays of (2, 2) matrices, returns 0 for rank-deficient
matrices.

*M* : array of (2, 2) matrices to inverse, shape (n, 2, 2)
Nr(   r(   r   Nr   r'   :0yE>r   )r   check_shaper   rf  rt  allr  r   )r   M_invprod1deltarank2	delta_invs         r   r   r   w  s?    	\Q'MM!EaAgJqAqz!EaAgJqAqz))E VVE]T"&&-//E	vve}}uH	 HHQWWQZ(	el?	q!QwZ	)E!Q'N1aj[*E!Q'N1aj[*E!Q'Nq!QwZ	)E!Q'NLr"   c                 h   [         R                  " SU S9  [        R                  " U 5      nU SS2SS4   U SS2SS4   -  nX SS2SS4   U SS2SS4   -  -
  n[        R                  " U5      S[        R                  " U5      -  :  n[        R
                  " U5      (       aX  U SS2SS4   U-  USS2SS4'   U SS2SS4   * U-  USS2SS4'   U SS2SS4   * U-  USS2SS4'   U SS2SS4   U-  USS2SS4'   U$ X4   nXSS4   U-  XSS4'   XSS4   * U-  XSS4'   XSS4   * U-  XSS4'   XSS4   U-  XSS4'   U) nXSS4   XSS4   -   n[        R                  " U5      S:  nSU-
  US-  U-   -  nXSS4   U-  XSS4'   XSS4   U-  XSS4'   XSS4   U-  XSS4'   XSS4   U-  XSS4'   U$ )	a|  
Inversion of arrays of (2, 2) SYMMETRIC matrices; returns the
(Moore-Penrose) pseudo-inverse for rank-deficient matrices.

In case M is of rank 1, we have M = trace(M) x P where P is the orthogonal
projection on Im(M), and we return trace(M)^-1 x P == M / trace(M)**2
In case M is of rank 0, we return the null matrix.

*M* : array of (2, 2) matrices to inverse, shape (n, 2, 2)
r  r  Nr   r'   r  r   r(   )r   r  r   rf  rt  r  )	r   r  r  r  r  rank01trtr_zeros	sq_tr_invs	            r   r   r     sC    	\Q'MM!EaAgJqAqz!EaAgJqAqz))EVVE]T"&&-//E	vve}}1a7e+aAgAq!G*u,aAgAq!G*u,aAg1a7e+aAg* L! a{^e3Qkq!n_u4Qkq!n_u4Qka{^e3Qkq!|_qA.FF2J&[RU8^4	1o	9al1o	9al1o	9al1o	9alLr"   c                 T    U SS2[         R                  [         R                  4   U-  $ )z.
Scalar product between scalars and matrices.
N)r   newaxis)scalarr   s     r   r   r     s#     !RZZ+,Q..r"   c                 4    [         R                  " U / SQ5      $ )z,
Transposition of an array of matrices *M*.
)r   r(   r'   )r   	transposer  s    r   r   r     s     <<9%%r"   c                 &   US;   d   eU R                   nUS:X  d   eUR                   nUS:X  d   eU R                  nUSS u  pgUS   UR                  S   :X  d   e[        R                  " US   [        R                  S9n[        R
                  " U 5      n	US:X  a;  [        U5       H*  n
[        U5       H  nXU* U
-   U-  U4   U	SS2X4'   M     M,     U	$ [        U5       H)  n
[        U5       H  nXX* U-   U-  4   U	SS2X4'   M     M+     U	$ )zo
Roll an array of matrices along *axis* (0: rows, 1: columns) according to
an array of indices *roll_indices*.
r   r'   r   r'   Nr   r$   )r   r   r   r,  r-  rf  r  )r   roll_indicesr   r   	ndim_rollshr  r   vec_indicesM_rollirics               r   r   r     s,   
 6>>66D199!!I>>	
Bbc7DAa5L&&q))))))BqE2K ]]1Fqy(BAh$%\M"4D3I2&M$Nq"y!   M (BAh$%2b8HA7M&M$Nq"y!   Mr"   c                 l   [        U [        [        45      (       d   e[        S U  5       5      (       d   e[        R
                  " U  Vs/ s H  n[        U5      PM     sn5      n[        R                  " X"S   -
  S:H  5      (       d   e[        U 5      nUS   n[        R
                  " U S   S   5      nUR                  nUR                  S   X4/n[        R                  " XvS9n[        U5       H7  n	[        U5       H%  n
[        R
                  " X	   U
   5      USS2X4'   M'     M9     U$ s  snf )a  
Build an array of matrices from individuals np.arrays of identical shapes.

Parameters
----------
M
    ncols-list of nrows-lists of shape sh.

Returns
-------
M_res : np.array of shape (sh, nrow, ncols)
    *M_res* satisfies ``M_res[..., i, j] = M[i][j]``.
c              3   N   #    U  H  n[        U[        [        45      v   M     g 7frO   )
isinstancetuplelist).0items     r   	<genexpr>(_to_matrix_vectorized.<locals>.<genexpr>  s     =14z$..1s   #%r   r$   N)r  r  r  r  r   r   lenr%   r   r1   r  )r   r  c_vecr  r   M00dtr  M_retirowicols              r   r   r     s	    a%''''=1=====JJa0adD	a01E66%a.A%&&&&AAaA
**QqT!W
C	B
))A,	BHHR"Ea!HD#%::agdm#<E!T-    L 1s   D1c                    UR                   S:X  d   eUS;   d   eU R                  u  pEUS:X  a  UR                  S   X%/nOUR                  S   XB/nU R                  n[        R                  " XgS9nUS:X  a,  [        U5       H  n	XU-  U	-   SS24   USS2U	SS24'   M     U$ [        U5       H  n
U SS2X-  U
-   4   USS2SS2U
4'   M     U$ )z
Extract selected blocks of a matrices *M* depending on parameters
*block_indices* and *block_size*.

Returns the array of extracted matrices *Mres* so that ::

    M_res[..., ir, :] = M[(block_indices*block_size+ir), :]
r'   r  r   r$   N)r   r   r%   r   r1   r  )r   block_indicesr   r   r  r   r  r  M_resr  r  s              r   r   r     s     """6>>77DAqy!!!$j4!!!$a4	
BHHR"Eqy
#Bz!9"!<q @AE!R(O $ L 
#BM$<R$? @AE!Q(O $ Lr"   )Nr  i  )rU   numpyr   
matplotlibr   matplotlib.trir   matplotlib.tri._trifinderr   matplotlib.tri._tritoolsr   __all__r   r   r	   r   rI  r   r   r   r  r  r   r   r   r   r   r   r   rY   r"   r   <module>r     s      ( / 0
NVO VOr3:O 3:l_@? _@H	P0 P0nI IX). )R. Rj6. 6vA AHCh<+\/&8<r"   