
    Ti7                         d Z ddlZddlmZmZmZmZ ddlmZ dZ	d Z
d Zd	 Zd
 Zd Zd Zd Zd Zd ZddZddZd Zd ZddZd Zd Zd ZddZddZd ZdS )z
This module provides some basic linear algebra procedures.

Translated from Zaikun Zhang's modern-Fortran reference implementation in PRIMA.

Dedicated to late Professor M. J. D. Powell FRS (1936--2015).

Python translation by Nickolai Belakovski.
    N   )	DEBUGGINGEPSREALMAXREALMIN)presentFc                     t           st          j        | |          S d}t          t	          |                     D ]}|| |         ||         z  z  }|S )Nr   )USE_NAIVE_MATHnpdotrangelenxyresultis       x/var/www/development/aibuddy-work/election-extract/venv/lib/python3.11/site-packages/scipy/_lib/pyprima/common/linalg.pyinprodr      sW     va||F3q66]]  !A$1+M    c                     t          j        |j        d                   }t          |j        d                   D ]}t	          | |d d |f                   ||<    |S )Nr   )r   zerosshaper   r   r   s       r   	matprod12r   %   sZ    Xagaj!!F171: ' '1a1g&&q		Mr   c                     t          j        | j        d                   }t          | j        d                   D ]}|| d d |f         ||         z  z  }|S Nr   r   r   r   r   r   r   s       r   	matprod21r   ,   sY    Xagaj!!F171: ! !!AAAqD'AaD. Mr   c           	      $   t          j        | j        d         |j        d         f          }t          |j        d                   D ]H}t          | j        d                   D ]+}|d d |fxx         | d d |f         |||f         z  z  cc<   ,I|S r   r   )r   r   r   r   js        r   	matprod22r!   3   s    Xqwqz171:.//F171: . .qwqz"" 	. 	.A111a4LLLAaaadGa1g--LLLL	.Mr   c                 X   t           s| |z  S t          | j                  dk    r(t          |j                  dk    rt          | |          S t          | j                  dk    r(t          |j                  dk    rt	          | |          S t          | j                  dk    r(t          |j                  dk    rt          | |          S t          | j                  dk    r(t          |j                  dk    rt          | |          S t          d| j         d|j                   )Nr      zInvalid shapes for x and y: z and )r
   r   r   r   r   r   r!   
ValueError)r   r   s     r   matprodr%   ;   s    s

17||qS\\Q..a||	QW		s17||q00A	QW		s17||q00A	QW		s17||q00AOOOagOOPPPr   c                     t           st          j        | |          S t          j        t	          |           t	          |          f          }t          t	          |                     D ]}| ||         z  |d d |f<   |S N)r
   r   outerr   r   r   r   s       r   outprodr)   J   su     x1~~Xs1vvs1vv&''F3q66]] $ $qt8F111a4LLMr   c           	      ^   t           s(t          j                            | |d           d         S | j        d         }| j        d         }t          ||          }t          j        |          }|                                }t          |dz
  dd          D ]}	t          ||d d |	f                   }
t          t          j
        |          t          j
        |d d |	f                             }t          |
|          rd||	<   p|
||	         z  ||	<   |||	         | d d |	f         z  z
  }|S )N)rcondr   r   )r
   r   linalglstsqr   minr   copyr   r   absisminor)AbQRdiagmnrankr   r   r   yqyqas               r   lsqrr<   S   s    4yq!40033	
A	
Aq!99D
A	A4!8R$$ # #AqAwRVAYYqAw002s 	#AaDDa=AaDAaD1QQQT7N"AAHr   c                    t           st          j        | |          S t          j        |           st	          |           }n6t          j        |          st	          |          }nt	          t          j        | |g                    }t          j        t          |          t          |          g          }|d         t          j        t                    k    rK|d         t          j        t          dz            k     r%t          j        t          ||z                      }nP|d         dk    rB|d         t          j        |d         |d         z  |d         |d         z  z  dz             z  }nd}|S )Nr   r    @)r
   r   hypotisfiniter1   arrayr/   maxsqrtr   r   sum)x1x2rr   s       r   r?   r?   j   s4     xB;r?? GG[__ 
GG"b""##Hc!ffc!ff%&&Q4"''""""qtbggck.B.B'B'BAaC!!AAqTAXX!rw!QqT	AaD1I6:;;;AAAHr   c                     t           st          j                            |           S t          j        t          d | D                                 }|S )Nc                     g | ]}||z  S  rJ   ).0xis     r   
<listcomp>znorm.<locals>.<listcomp>   s    ,,,B"R%,,,r   )r
   r   r-   normrC   rD   )r   r   s     r   rN   rN   }   sK     !y~~a    WS,,!,,,--..FMr   c                     t          t          |           t          j        t          |                     z
            |k    S r'   )primasumr1   r   trilr3   tols     r   istrilrT      .    CFFRWSVV__,--44r   c                     t          t          |           t          j        t          |                     z
            |k    S r'   )rP   r1   r   triurR   s     r   istriurX      rU   r   c                 n   t           st          j                            |           S |                                 } | j        d         }t          |           r| j        }t          j        ||f          }t          |          D ]M}d|||f         z  |||f<   t          |d |d |f         |d ||f                    |||f         z  |d ||f<   N|j        S t          |           rtt          j        ||f          }t          |          D ]M}d| ||f         z  |||f<   t          |d |d |f         | d ||f                    | ||f         z  |d ||f<   Nnt          |           \  }}}|j        }t          j        ||f          }t          |dz
  dd          D ]M}|d d |f         t          |d d |dz   |f         ||dz   ||f                   z
  |||f         z  |d d |f<   Nt          j        |t                    }t          j        d|dz
  |          ||<   |d d |f         j        }|S )Nr   r   r,   dtype)r
   r   r-   invr0   r   rT   Tr   r   r%   rX   qrintlinspace)r3   r8   RBr   r5   PInvPs           r   r\   r\      sm     y}}Q	A	
Aayy CHaVq 	? 	?A!AqD'kAadG"1"bqb&	1RaRU8444qAw>Abqb!eHHs
	 HaVq 	? 	?A!AqD'kAadG"1"bqb&	1RaRU8444qAw>Abqb!eHH	?
 Q%%1aCHaVq1ub"%% 	R 	RAAw111a!eAg:!a%'1*!F!FF!AqD'QAaaadGGx%%%+a1a((QaaagJLHr   c                    | j         d         }| j         d         }t          j        |          }| j        }t          j        d|dz
  |t
                    }t          |          D ]Q}t          j        t          t          |||dz   ||dz   f                   d          d          }|dk    r?|||z
  dz
  k    r3||z  }||         ||         c||<   ||<   |||gd d f         |||gd d f<   t          |dz
  |d          D ]}t          ||||gf                   j        }	t          j        t          |||f         |||f                   d          ||||gf<   t          ||dz   |dz   ||gf         |	          ||dz   |dz   ||gf<   t          |d d ||gf         |	          |d d ||gf<   S|j        }
||
|fS )Nr   r   rZ   axisr,   )r   r   eyer]   r`   r_   r   argmaxrP   	primapow2planerotappendr?   r%   )r3   r7   r8   r5   r]   rc   r    kr   Gra   s              r   r^   r^      s   	
A	
A
q		A	A
AqsAS)))A1XX 
4 
4Ihy1QqS5!AaC%<99BBBKKKq55Q!a%!)^^FA1qtJAaD!A$aVQQQY<Aq!faaaiLqsAr"" 	4 	4A1q!f9&&(A9U1QT7AadG%<%<a@@Aa!QiL%,Qq1uQU{QF/B-CQ%G%GAa!eAEkAq6!""1QQQAY<33Aaaa!QiLL		4 	
Aa7Nr   c                 4   t           st          j        | |          S |8| j        dk    rt          t	          | d                    S t          |           S |dk    rZt          j        | j        d                   }t          | j        d                   D ]}t          | dd|f                   ||<   |S |dk    rZt          j        | j        d                   }t          | j        d                   D ]}t          | |ddf                   ||<   |S dS )z
    According to its documentation, np.sum will sometimes do partial pairwise summation.
    For our purposes, when comparing, we want don't want to do anything fancy, and we
    just want to add things up one at a time.
    rf   Nr#   r   r   )r
   r   rD   ndimrP   r   r   r   )r   rg   r   r   s       r   rP   rP      s     $vad####|6Q;;x***+++q66M	!'!*%%qwqz"" 	% 	%AAaaadGF1II	!'!*%%qwqz"" 	% 	%AAadGF1II	 
r   c                     | | z  S )a@  
    Believe it or now, x**2 is not always the same as x*x in Python. In Fortran they
    appear to be identical. Here's a quick one-line to find an example on your system
    (well, two liner after importing numpy):
    list(filter(lambda x: x[1], [(x:=np.random.random(), x**2 - x*x != 0) for _ in range(10000)]))
    rJ   )r   s    r   rj   rj      s     Q3Jr   c           
      
   t           rt          |           dk    s
J d            t          t          j        |                     rd}d}nt          t          j        |                     rfdt          j        d          z  t          j        | d                   z  }dt          j        d          z  t          j        | d                   z  }nt          | d                   dk    rt          | d                   dk    rd}d}nTt          | d                   t          t          | d                   z  k    rt          j        | d                   }d}nt          | d                   t          t          | d                   z  k    rd}t          j        | d                   }nt          t          j        t          j        t                    t          j	        |           k     t          j	        |           t          j        t          dz            k                         r't          |           }| d         |z  }| d         |z  }n
t          | d                   t          | d                   k    ro| d         | d         z  }t          dt          |          t          j        d||z  z                       }|t          j        | d                   z  }d|z  }||z  }no| d         | d         z  }t          dt          |          t          j        d||z  z             g          }|t          j        | d                   z  }||z  }d|z  }t          j        ||g| |gg          }t           r|j        dk    sJ t          j        t          j        |                    sJ t          |d         |d         z
            t          |d	         |d
         z             z   dk    sJ t          j        dt          j        ddt          z                      }t+          ||          sJ t          t          j        t          j        |           t          j	        |           t          j        t          dz            k                         rbt          j                            |           }t          t          || z  |dgz
                      t          |||z            k    s
J d            |S )aP  
    As in MATLAB, planerot(x) returns a 2x2 Givens matrix G for x in R2 so that Y=G@x has Y[1] = 0.
    Roughly speaking, G = np.array([[x[0]/R, x[1]/R], [-x[1]/R, x[0]/R]]), where R = np.linalg.norm(x).
    0. We need to take care of the possibilities of R=0, Inf, NaN, and over/underflow.
    1. The G defined above is continuous with respect to X except at 0. Following this definition,
    G = np.array([[np.sign(x[0]), 0], [0, np.sign(x[0])]]) if x[1] == 0,
    G = np.array([[0, np.sign(x[1])], [np.sign(x[1]), 0]]) if x[0] == 0
    Yet some implementations ignore the signs, leading to discontinuity and numerical instability.
    2. Difference from MATLAB: if x contains NaN of consists of only Inf, MATLAB returns a NaN matrix,
    but we return an identity matrix or a matrix of +/-np.sqrt(2). We intend to keep G always orthogonal.
    r#   zx must be a 2-vectorr   r   r>   )r#   r#   )r   r   )r   r   )r   r   )r   r   g|=皙?g    .AzG @ X = [||X||, 0])r   r   anyr   isnanallisinfrC   signr1   r   logical_andr   r   rN   rB   rA   r   r@   maximumminimumisorthr-   )r   csrG   turn   rS   s           r   rk   rk      s"     31vv{{{2{{{ 	BHQKK /
bhqkk

 +

NRWQqT]]*

NRWQqT]]*
ad))q..S1YY!^^
ad))sS1YY
&
& GAaDMM
ad))sS1YY
&
& GAaDMM rww//"&));RVAYYQX[^Q^I_I_=_``aa 	QA!qA!qAA!A$ii#ad))##!qtAAs1vvrwq1Q3w//00A1AAAAAA!qtAQAAaC 0 0122A1AAAAA
1a&A2q'"##A  Uw%vbk!nn%%%%%1T7QtW$%%AdGag,=(>(>>!CCCCj"*VUS["A"ABBa~~r~bk!nnbfQii"''C-:P:P.PQQRR 	U	q!!As1Q3!Q<(())ScAg->->>>>@T>>>Hr   c                     d}t          |          |t          |           z  z   }t          |          d|z  t          |           z  z   }t          j        t          |          |k    ||k              S )a#  
    This function tests whether x is minor compared to ref. It is used by Powell, e.g., in COBYLA.
    In precise arithmetic, isminor(x, ref) is true if and only if x == 0; in floating point
    arithmetic, isminor(x, ref) is true if x is 0 or its nonzero value can be attributed to
    computer rounding errors according to ref.
    Larger sensitivity means the function is more strict/precise, the value 0.1 being due to Powell.

    For example:
    isminor(1e-20, 1e300) -> True, because in floating point arithmetic 1e-20 cannot be added to
    1e300 without being rounded to 1e300.
    isminor(1e300, 1e-20) -> False, because in floating point arithmetic adding 1e300 to 1e-20
    dominates the latter number.
    isminor(3, 4) -> False, because 3 can be added to 4 without being rounded off
    rs   r#   )r1   r   
logical_or)r   refsensitivityrefarefbs        r   r2   r2   E  sd      Ks88kCFF**Ds88a+oA..D=ST)44<888r   c                 *   t          j        | d          }t          rt          j        | d          t          j        | d          k    sJ t          j        |d          t          j        |d          k    sJ t          j        | d          t          j        |d          k    sJ t          |          r|dk    sJ t          |          r|nXt          j        ddt
          z  t          j        t          j        | d          t          j        | d                    z            }t          j        ||t          j        t          |                     z  |t          j        t          |                    z  g          }t          t          | |                    t          j
        |          z
  |k                                    pGt          t          ||           t          j
        |          z
            |k                                    }|S )zJ
    This procedure tests whether A = B^{-1} up to the tolerance TOL.
    r   r   gMbP?g      Y@)r   sizer   r   r{   r   rz   rB   r1   r%   rh   rv   )r3   rb   rS   r8   is_invs        r   isinvr   [  s    	1A  wq!}}1----wq!}}1----wq!}}1----3<< 	!8888 
i##2:dC#I
27STVW==Z\ZabcefZgZg@h@h4h#i#iC
&#sRVCFF^^+S26#a&&>>-AB
C
CC71a==!!BF1II-#5::<<o#gaQRmmVXV\]^V_V_F_B`B`ehAh@m@m@o@oF
 Mr   c           
         t           rt          |          r|dk    sJ t          j        | d          }|t          j        | d          k    rd}nt          j        t          t          |                               rd}nt          |          rt          t          | j        |           t          j	        |          z
            t          j
        ||t          j        t          |                     z            k                                    }nMt          t          | j        |           t          j	        |          z
            dk                                    }|S )zc
    This function tests whether the matrix A has orthonormal columns up to the tolerance TOL.
    r   r   F)r   r   r   r   ru   rP   r1   r%   r]   rh   rz   rB   rv   )r3   rS   num_varsis_orths       r   r|   r|   y  s*     3<< 	!8888 wq!}}H"'!Q--
(8CFF##
$
$ K3<< 	K713??RVH-=-==>>"*SRUXZX^_bcd_e_eXfXfRfBgBggllnnGG713??RVH-=-==>>!CHHJJG
 Nr   c                      t          |           dk    rt          d          t          d | D                       }t          d | D                       }dt          z  t          |d          z  |z  S )aS  
    Get a relative tolerance for a set of arrays. Borrowed from COBYQA

    Parameters
    ----------
    *arrays: tuple
        Set of `numpy.ndarray` to get the tolerance for.

    Returns
    -------
    float
        Relative tolerance for the set of arrays.

    Raises
    ------
    ValueError
        If no array is provided.
    r   z$At least one array must be provided.c              3   $   K   | ]}|j         V  d S r'   )r   rK   rA   s     r   	<genexpr>z!get_arrays_tol.<locals>.<genexpr>  s$      ..euz......r   c           	   3      K   | ]D}t          j        t          j        |t          j        |                             d           V  EdS )      ?)initialN)r   rB   r1   r@   r   s     r   r   z!get_arrays_tol.<locals>.<genexpr>  s^         	rveBK../00#>>>     r   g      $@r   )r   r$   rB   r   )arraysr   weights      r   get_arrays_tolr     s    & 6{{a?@@@..v.....D      F #:D#&//r   )r   r'   )__doc__numpyr   constsr   r   r   r   r   r
   r   r   r   r!   r%   r)   r<   r?   rN   rT   rX   r\   r^   rP   rj   rk   r2   r   r|   r   rJ   r   r   <module>r      s        4 4 4 4 4 4 4 4 4 4 4 4               Q Q Q    .  &  5 5 5 55 5 5 5  >  2   4  X X Xv9 9 9,   <   @0 0 0 0 0r   