
    Rie%                         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                 :  
 ddl m}                                 t                              |                     }                    |d          
fd|D             fdD             }t          
          }|                    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                 F    g | ]}|v                      |          |S r   )add)r   r$   seens     r   r    z3_get_conversion_matrix_for_expr.<locals>.<listcomp>&   s-    TTTQ!t))txxPQ{{)q)))r!   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#   setissubsetsolver   )exprtarget_unitsr   r   expr_dimcanon_dim_unitscanon_expr_unitscamatexprmatres_exponentsr1   r%   r(   r-   s     `       @@@@r   _get_conversion_matrix_for_exprr?      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+,,$$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   4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$   r8   r   s     r   	<genexpr>zconvert_to.<locals>.<genexpr>f   sC           'q,DD            r!   c                 ,    t          | t                    S rC   )
isinstancer   )r   s    r   <lambda>zconvert_to.<locals>.<lambda>m   s    jH&=&= r!   c                 0    |                                S rC   rD   )r   r8   r   s    r   rI   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 rC   r   )r   ys     r   rI   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!   )	rH   r	   r   argsr
   baseexpr   get_quantity_scale_factor)r7   rO   r   s    r   rO   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prO   s      r   rF   zconvert_to.<locals>.<genexpr>   sS       ,# ,#/3q!!!!$$	$Q	&*,# ,# ,# ,# ,# ,#r!   )sympy.physics.unitsr   get_unit_systemrH   r   r   r   fromiterrP   r   r   hasreplacer?   r	   zip)r7   r8   r   r   depmatexpr_scale_factorrO   s    ``   @r   rE   rE   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   rW   s     r   
<dictcomp>z%quantity_simplify.<locals>.<dictcomp>   s    777!Q^777r!   c                     | j         S rC   )	dimension)r$   s    r   rI   z#quantity_simplify.<locals>.<lambda>   s    Q[ r!   rU   r   c                 &    i | ]}||j         z  S r   rc   )r   virefs     r   re   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   rd   
ValueErrorr   rY   r3   r   r#   dimensional_dependenciesitemsderived_unitsr+   rE   )r7   r`   r   rW   dr0   vr%   dim_exprdim_depstarget_dimensionds_dimds_dim_depstarget_unitrj   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 r/   r   )r   keyvals      r   re   z5check_dimensions.<locals>.addDict.<locals>.<dictcomp>   s#    BBBHCCr!   )rr   )dict1dict2dict3r   values        r   addDictz!check_dimensions.<locals>.addDict   sn     #5"E"++-- 	3 	3JCe||u %c
 25:BBBBBBr!   r   FT)r   rU   z(addends have incompatible dimensions: {}c              3   @   K   | ]}t          |t                    V  d S rC   )rH   r   r   r$   s     r   rF   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!   )rX   r   rY   rl   r   r3   r#   r4   rP   r   r'   r	   	make_argsr[   r   r   r   free_symbolsextendrr   tuplesortedr   rn   rp   formatanyfuncrm   )r7   r   r   r   addsDIM_OFadesetaidimsskipdimdictr$   repsms                  r   check_dimensionsr      sU    /.....,*,[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::>>$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!   )r@   )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   r?   rE   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!   