
    MZd%                         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&y)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} |j                         }t        |j	                  |             }|j                  |d      }|D cg c]  }t        |j	                  |             }}|D 	cg c]  }|j                  |d      D ]  }	|	  }
}}	t        |      }|j                  t        |
            sy t               }|
D 	cg c]  }	|	|v r|j                  |	      r|	 }
}	 ||
D 	cg c]3  }|D 	cg c]%  }	|j                  |	d      j                  |d      ' c}	5 c}	}      } ||
D cg c]  }|j                  |d       c}      }	 |j                  |      }|S c c}w c c}	}w c c}	w c c}	w c c}	}w c c}w # t        $ r Y y w xY w)Nr   )MatrixTmark_dimensionless)sympy.matrices.denser   get_dimension_systemr   get_dimensional_exprget_dimensional_dependenciessetissubsetaddgetsolver   )exprtarget_unitsunit_systemr   dimension_systemexpr_dimdim_dependenciesxtarget_dimsicanon_dim_unitscanon_expr_unitsseenjcamatkexprmatres_exponentss                     :/usr/lib/python3/dist-packages/sympy/physics/units/util.py_get_conversion_matrix_for_exprr4      s   +"77999$?@H'DDXbfDgKWXa9[==a@AXKX"-  BQ7G7d7def{7d  8A  B!q  Bq  BO  B+,$$S%9:5D"1TQ!t)txxPQ{qTOT  IX  Y  DEr}~mn%BB1Y]B^bbcdfgh~  Y  ZE/JQ&**1a0JKGG, % Y B U~  YJ $ sN   !E+0!E0	E6E6$E61	F 
:*E;$F 
7FF ;F 
	FFc                    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              s,| j                  t              r| j                  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   8   K   | ]  }t        |        y wN
convert_to).0r*   r#   r$   s     r3   	<genexpr>zconvert_to.<locals>.<genexpr>f   s"        'q,D  s   c                 "    t        | t              S r7   )
isinstancer   )r(   s    r3   <lambda>zconvert_to.<locals>.<lambda>m   s    jH&=     c                 (    | j                        S r7   r8   )r(   r#   r$   s    r3   r>   zconvert_to.<locals>.<lambda>n   s    all<= r?   c           	      (   t        | t              r+t        d | j                  D cg c]
  } |       c}      S t        | t              r | j
                        | j                  z  S t        | t              rj                  |       S | S c c}w )Nc                     | |z  S r7    )r(   ys     r3   r>   z<convert_to.<locals>.get_total_scale_factor.<locals>.<lambda>r   s
    q1u r?   )	r=   r	   r   argsr
   baseexpr   get_quantity_scale_factor)r"   r*   get_total_scale_factorr$   s     r3   rI   z*convert_to.<locals>.get_total_scale_factorp   s~    dC ,48II>q'*>@ @c")$))4@@h'88>> ?s   B
c              3   F   K   | ]  \  }}d  |      z  |z  |z    yw)   NrC   )r:   uprI   s      r3   r;   zconvert_to.<locals>.<genexpr>   s/      ,#/3q!!!$	$Q	&*,#s   !)sympy.physics.unitsr   get_unit_systemr=   r   r   r   fromiterrE   r   r   hasreplacer4   r	   zip)r"   r#   r$   r   depmatexpr_scale_factorrI   s    ``   @r3   r9   r9   3   s    X /,*,,[9KlXu$56$~$||  YY    	  4=D<(LdH%$((8*<||==? -T<MF~.t4s|| ,#L&!,#  # # #r?   Nacross_dimensionsc           	      x   | j                   s| j                  t        t              s| S | j	                  t              }| j                  |D ci c]  }||j                   c}      } t        | j	                  t              d       }|D ]p  }t        ||         dk(  rt        t        ||               }|d   |d   j                  z  }| j                  |dd D ci c]  }|||j                  z   c}      } r |r|t        d      t        j                  |      }|j                         }	|j                  |       }
|	j!                  |
d      }d}|	j"                  j%                         D ]  \  }}||k(  s|} n || S |j&                  j)                  |      }|rt+        | ||      } | S c c}w c c}w )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                     | j                   S r7   )	dimension)r*   s    r3   r>   z#quantity_simplify.<locals>.<lambda>   s
    Q[[ r?   rK   r   Nz:unit_system must be specified if across_dimensions is TrueTr   )is_AtomrQ   r   r   atomsxreplacescale_factorr   lenlistr   
ValueErrorr   rO   r   r   r   dimensional_dependenciesitemsderived_unitsr    r9   )r"   rV   r$   rM   dr0   vrefvir%   dim_exprdim_depstarget_dimensionds_dimds_dim_depstarget_units                   r3   quantity_simplifyrn      s   , ||488FH5 	

6A==Q7!Q^^+78D 	TZZ!#89A Hqt9>1d1Q4$$$}}!"F"b#boo"55FGH  YZZ 00=,7,L,L,N33D9#@@^b@c04#3#L#L#R#R#T 	FKh&#) 	
 #K!//334DEdK=DKM 8 Gs   F2F7
c           
         ddl m}  |j                  |      }d }| j                  t              }|j                         j                  }|D ]5  }t               }|j                  D ]  }|j                  r|j                  d       "g }	d}
i }t        j                  |      D ]f  }|j                  t              rt        |j!                  |            }|j                  t              r || ||            }W|j"                  sdd}
 n |	j%                  |j'                                |
r|j                  t)        t+        |	t,                           t/        |      dkD  st1        d	j3                  |             8 i }| j                  t              D ]V  }t5        d
 |j                  D              s  |j6                  |j                  D cg c]  }|j                  r| c} ||<   X | j9                  |      S c c}w )z[Return expr if units in addends have the same
    base dimensions, else raise a ValueError.r   r   c                     i | |}|j                         D ]  \  }}|| v s||v s|| |   z   ||<    |j                         D ci c]  \  }}|dk7  s|| c}}S c c}}w )z]Merge dictionaries by adding values of common keys and
        removing keys with value of 0.r   )rb   )dict1dict2dict3keyvaluevals         r3   addDictz!check_dimensions.<locals>.addDict   su     #5"E"++- 	3JCe|u %c
 25:	3 ).BHCCBBBs   AArC   FT)rt   rK   z(addends have incompatible dimensions: {}c              3   <   K   | ]  }t        |t                y wr7   )r=   r   )r:   r*   s     r3   r;   z#check_dimensions.<locals>.<genexpr>   s     8Az!Y'8s   )rN   r   rO   r[   r   r   r   r   rE   	is_numberr   r	   	make_argsrQ   r   r   r   free_symbolsextendrb   tuplesortedr   r^   r`   formatanyfuncr\   )r"   r$   r   rw   addsDIM_OFadesetaidimsskipdimdictr*   repsms                  r3   check_dimensionsr      s    /,*,,[9KC ::c?D--/LLF R&& 	RB||		"DDG]]2& 55?!+"B"B1"EFA55#%gvay9G^^D KK(		%t1A BCDu:>$BII%PR R'	RR4 DZZ_ 7888aff6666 7DG7
 ==6s   H
)H
)SI)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   r4   r9   boolrn   r   rC   r?   r3   <module>r      s\     $  "  '    & & : E / 3 5 *8N#bAt AH8r?   