
    Ed%                         d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZmZ ddlmZ ddlmZ ddlmZ ddl m!Z! d Z"ddZ#dde$fdZ%ddZ&dS )zA
Several methods to simplify expressions involving unit objects.
    )reduce)Iterable)Optional)default_sort_key)Add)Tuple)Mul)Pow)ordered)sympify)NonInvertibleMatrixError)	DimensionDimensionSystem)Prefix)Quantity
UnitSystem)siftc                 4  
 ddl m}                                 t                              |                     }                    |d          
fd|D             fdD             }d 
D             }|                    t          |                    sd S t                      fd|D             } |fd	|D                       } |
fd
|D                       }	 |                    |          }	n# t          $ r Y d S w xY w|	S )Nr   )MatrixTmark_dimensionlessc                 T    g | ]$}t                              |                    %S  )r   get_dimensional_expr).0xunit_systems     8lib/python3.11/site-packages/sympy/physics/units/util.py
<listcomp>z3_get_conversion_matrix_for_expr.<locals>.<listcomp>   s/    XXXa9[==a@@AAXXX    c                 H    g | ]}                     |d           D ]}|S )Tr   )get_dimensional_dependencies)r   r   idimension_systems      r   r    z3_get_conversion_matrix_for_expr.<locals>.<listcomp>   s]      B  B  BQ7G7d7def{7d  8A  8A  B  B!q  B  B  B  Br!   c                     h | ]}|S r   r   r   r$   s     r   	<setcomp>z2_get_conversion_matrix_for_expr.<locals>.<setcomp>    s    444a444r!   c                 F    g | ]}|v                      |          |S r   )add)r   r$   seens     r   r    z3_get_conversion_matrix_for_expr.<locals>.<listcomp>&   s2    TTTQ!t)TtxxPQ{{TqTTTr!   c                 0    g | ]fd D             S )c                 f    g | ]-}                     |d                               d          .S )Tr   r   )r#   get)r   r$   r%   js     r   r    z>_get_conversion_matrix_for_expr.<locals>.<listcomp>.<listcomp>(   sA    ~~~mn%BB1Y]B^^bbcdfghh~~~r!   r   )r   r/   r%   target_dimss    @r   r    z3_get_conversion_matrix_for_expr.<locals>.<listcomp>(   sJ      Y  Y  Y  DE~~~~~r}~~~  Y  Y  Yr!   c                 <    g | ]}                     |d           S r   )r.   )r   kdim_dependenciess     r   r    z3_get_conversion_matrix_for_expr.<locals>.<listcomp>)   s*    JJJQ&**1a00JJJr!   )
sympy.matrices.denser   get_dimension_systemr   r   r#   issubsetsetsolver   )exprtarget_unitsr   r   expr_dimcanon_dim_unitscanon_expr_unitscamatexprmatres_exponentsr4   r%   r+   r0   s     `       @@@@r   _get_conversion_matrix_for_exprrB      s   ++++++"779999$??@@H'DDXbfDggXXXX<XXXK B  B  B  B+  B  B  BO44#3444$$S%9%9:: t55DTTTT/TTTOF  Y  Y  Y  Y  Y  IX  Y  Y  Y  Z  ZEfJJJJ/JJJKKGG,,#   tt s   1D 
DDSIc                 f   ddl m}  |j                  t          t          t
          f          sgt          | t                    r&t          j        fd| j        D                       S t          |           } t                    t          | t                    s5|                     t                    r|                     d fd          } fdt          |           }|| S  |           }|t          j        fdt          |          D                       z  S )	a  
    Convert ``expr`` to the same expression with all of its units and quantities
    represented as factors of ``target_units``, whenever the dimension is compatible.

    ``target_units`` may be a single unit/quantity, or a collection of
    units/quantities.

    Examples
    ========

    >>> from sympy.physics.units import speed_of_light, meter, gram, second, day
    >>> from sympy.physics.units import mile, newton, kilogram, atomic_mass_constant
    >>> from sympy.physics.units import kilometer, centimeter
    >>> from sympy.physics.units import gravitational_constant, hbar
    >>> from sympy.physics.units import convert_to
    >>> convert_to(mile, kilometer)
    25146*kilometer/15625
    >>> convert_to(mile, kilometer).n()
    1.609344*kilometer
    >>> convert_to(speed_of_light, meter/second)
    299792458*meter/second
    >>> convert_to(day, second)
    86400*second
    >>> 3*newton
    3*newton
    >>> convert_to(3*newton, kilogram*meter/second**2)
    3*kilogram*meter/second**2
    >>> convert_to(atomic_mass_constant, gram)
    1.660539060e-24*gram

    Conversion to multiple units:

    >>> convert_to(speed_of_light, [meter, second])
    299792458*meter/second
    >>> convert_to(3*newton, [centimeter, gram, second])
    300000*centimeter*gram/second**2

    Conversion to Planck units:

    >>> convert_to(atomic_mass_constant, [gravitational_constant, speed_of_light, hbar]).n()
    7.62963087839509e-20*hbar**0.5*speed_of_light**0.5/gravitational_constant**0.5

    r   r   c              3   :   K   | ]}t          |          V  d S N
convert_to)r   r$   r;   r   s     r   	<genexpr>zconvert_to.<locals>.<genexpr>f   sC           'q,DD            r!   c                 ,    t          | t                    S rF   )
isinstancer   )r   s    r   <lambda>zconvert_to.<locals>.<lambda>m   s    jH&=&= r!   c                 0    |                                S rF   rG   )r   r;   r   s    r   rL   zconvert_to.<locals>.<lambda>n   s    all<== r!   c                 $   t          | t                    r"t          d fd| j        D                       S t          | t                    r | j                  | j        z  S t          | t                    r                    |           S | S )Nc                     | |z  S rF   r   )r   ys     r   rL   z<convert_to.<locals>.get_total_scale_factor.<locals>.<lambda>r   s
    q1u r!   c                 &    g | ]} |          S r   r   )r   r$   get_total_scale_factors     r   r    z>convert_to.<locals>.get_total_scale_factor.<locals>.<listcomp>s   s%    >>>q''**>>>r!   )	rK   r	   r   argsr
   baseexpr   get_quantity_scale_factor)r:   rR   r   s    r   rR   z*convert_to.<locals>.get_total_scale_factorp   s    dC   	?,,>>>>DI>>>@ @ @c"" 	?))$)44@@h'' 	?88>>>r!   Nc              3   F   K   | ]\  }}d  |          z  |z  |z  V  dS )   Nr   )r   uprR   s      r   rI   zconvert_to.<locals>.<genexpr>   sS       ,# ,#/3q!!!!$$	$Q	&*,# ,# ,# ,# ,# ,#r!   )sympy.physics.unitsr   get_unit_systemrK   r   r   r   fromiterrS   r   r   hasreplacerB   r	   zip)r:   r;   r   r   depmatexpr_scale_factorrR   s    ``   @r   rH   rH   3   s   X /.....,*,[99KlXu$566 &$~$  |          Y          	  4==D<((LdH%% ?$((8*<*< ?||=======? ?      -T<MMF ..t44s| ,# ,# ,# ,#L&!!,# ,# ,#  #  # # #r!   FNacross_dimensionsc                    | j         s |                     t          t                    s| S |                     t                    }|                     d |D                       } t          |                     t                    d           }|D ]}}t          ||                   dk    rt          t          ||                             }|d         |d         j
        z  |                     fd|dd         D                       } ~|r|t          d          t          j        |          }|                                }|                    |           }|                    |d	          }	d}
|j                                        D ]\  }}||	k    r|}
 n|
| S |j                            |
          }|rt+          | ||          } | S )
a  Return an equivalent expression in which prefixes are replaced
    with numerical values and all units of a given dimension are the
    unified in a canonical manner by default. `across_dimensions` allows
    for units of different dimensions to be simplified together.

    `unit_system` must be specified if `across_dimensions` is True.

    Examples
    ========

    >>> from sympy.physics.units.util import quantity_simplify
    >>> from sympy.physics.units.prefixes import kilo
    >>> from sympy.physics.units import foot, inch, joule, coulomb
    >>> quantity_simplify(kilo*foot*inch)
    250*foot**2/3
    >>> quantity_simplify(foot - 6*inch)
    foot/2
    >>> quantity_simplify(5*joule/coulomb, across_dimensions=True, unit_system="SI")
    5*volt
    c                     i | ]
}||j         S r   scale_factor)r   rZ   s     r   
<dictcomp>z%quantity_simplify.<locals>.<dictcomp>   s    777!Q^777r!   c                     | j         S rF   )	dimension)r$   s    r   rL   z#quantity_simplify.<locals>.<lambda>   s    Q[ r!   rX   r   c                 &    i | ]}||j         z  S r   rf   )r   virefs     r   rh   z%quantity_simplify.<locals>.<dictcomp>   s"    FFF"b#bo"5FFFr!   Nz:unit_system must be specified if across_dimensions is TrueTr   )is_Atomr^   r   r   atomsxreplacer   lenlistr   rg   
ValueErrorr   r\   r6   r   r#   dimensional_dependenciesitemsderived_unitsr.   rH   )r:   rc   r   rZ   dr3   vr%   dim_exprdim_depstarget_dimensionds_dimds_dim_depstarget_unitrm   s                 @r   quantity_simplifyr      s   , | 488FH55  	

6A==77Q77788D 	TZZ!!#8#899A H Hqt99> 	1d1Q4$$}}FFFF!""FFFGG >  	[YZZZ 0==,7,L,L,N,N33D99#@@^b@cc04#3#L#R#R#T#T 	 	FKh& #)   	K!/334DEE 	>dK==DKr!   c           
      B   ddl m}  |j        |          }d }|                     t                    }|                                j        }|D ]b}t                      }|j        D ]H}|j	        r|
                    d            g }	d}
i }t          j        |          D ]y}|                    t                    r"t          |                    |                    }|                    t                    r || ||                    }n|j        rd}
 nz|	                    |                                           |
sk|
                    t)          t+          |	t,                                         t/          |          dk    r"t1          d	                    |                    Jdi }|                     t                    D ]<}t5          d
 |j        D                       r |j        d |j        D              ||<   =|                     |          S )z[Return expr if units in addends have the same
    base dimensions, else raise a ValueError.r   r   c                     i | |}|                                 D ]\  }}|| v r||v r|| |         z   ||<   d |                                 D             S )z]Merge dictionaries by adding values of common keys and
        removing keys with value of 0.c                 &    i | ]\  }}|d k    ||S r2   r   )r   keyvals      r   rh   z5check_dimensions.<locals>.addDict.<locals>.<dictcomp>   s'    BBBHCBCBBBr!   )ru   )dict1dict2dict3r   values        r   addDictz!check_dimensions.<locals>.addDict   st     #5"E"++-- 	3 	3JCe| 3u 3 %c
 25:BBBBBBr!   r   FT)r   rX   z(addends have incompatible dimensions: {}c              3   @   K   | ]}t          |t                    V  d S rF   )rK   r   r'   s     r   rI   z#check_dimensions.<locals>.<genexpr>   s,      88Az!Y''888888r!   c                      g | ]}|j         	|S r   )	is_numberr'   s     r   r    z$check_dimensions.<locals>.<listcomp>   s/     6 6 666 6 6r!   )r[   r   r\   ro   r   r6   r#   r8   rS   r   r*   r	   	make_argsr^   r   r   r   free_symbolsextendru   tuplesortedr   rq   rs   formatanyfuncrp   )r:   r   r   r   addsDIM_OFadesetaidimsskipdimdictr$   repsms                  r   check_dimensionsr      sY    /.....,*,[99KC C C ::c??D--//LF R R& 	R 	RB| 		"DDG]2&&  55?? G!+"B"B1"E"EFFA55## %ggvvayy99GG^ DE KK((( R		%t1A B B BCCDDDu::> R$BII%PPR R R'	R0 DZZ__ 7 78888888 	7af 6 666 6 6 7DG ==r!   )rC   )FN)'__doc__	functoolsr   collections.abcr   typingr   sympyr   sympy.core.addr   sympy.core.containersr   sympy.core.mulr	   sympy.core.powerr
   sympy.core.sortingr   sympy.core.sympifyr   sympy.matrices.commonr   sympy.physics.units.dimensionsr   r   sympy.physics.units.prefixesr   sympy.physics.units.quantitiesr   sympy.physics.units.unitsystemr   sympy.utilities.iterablesr   rB   rH   boolr   r   r   r!   r   <module>r      s          $ $ $ $ $ $       " " " " " "       ' ' ' ' ' '                   & & & & & & & & & & & & : : : : : : E E E E E E E E / / / / / / 3 3 3 3 3 3 5 5 5 5 5 5 * * * * * *  8N# N# N# N#bA At A A A AH8 8 8 8 8 8r!   