o
    jg                     @   s   d Z ddlmZ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d	lmZ d
dlmZ G dd deZdS )zG
Unit system for physical quantities; include definition of constants.
    )DictSet)Add)
DerivativeFunction)Mul)Pow)S)_QuantityMapperQuantity   )	Dimensionc                       s   e Zd ZdZi Zddddi fdeeef f fddZdd	 Z	d
d Z
ddddi fdeeef fddZdd Z fddZ fddZedd Zedd Zedd Zedd Zedeeef fddZdd  Zd!d" Zdee fd#d$Z  ZS )%
UnitSystemz
    UnitSystem represents a coherent set of units.

    A unit system is basically a dimension system with notions of scales. Many
    of the methods are defined in the same way.

    It is much better if all base units have a symbol.
      Nderived_unitsc                    sV   | t j|< || _|| _|| _|| _tt|t|B | _t|| _|| _	t
   d S N)r   _unit_systemsnamedescr_base_units_dimension_systemtupleset_units_derived_unitssuper__init__)self
base_unitsunitsr   r   dimension_systemr   	__class__r   V/var/www/html/zoom/venv/lib/python3.10/site-packages/sympy/physics/units/unitsystem.pyr      s   

zUnitSystem.__init__c                 C   s*   | j dkr| j S dddd | jD  S )z
        Return the name of the system.

        If it does not exist, then it makes a list of symbols (or names) of
        the base dimensions.
        r   zUnitSystem((%s)), c                 s   s    | ]}t |V  qd S r   )str.0dr   r   r%   	<genexpr>8   s    
z%UnitSystem.__str__.<locals>.<genexpr>)r   joinr   r   r   r   r%   __str__-   s
   

zUnitSystem.__str__c                 C   s   dt | j S )Nz<UnitSystem: %s>)reprr   r-   r   r   r%   __repr__;   s   zUnitSystem.__repr__c                 C   s8   | j t| }| jt| }t|||||i | j|S )a  Extend the current system into a new one.

        Take the base and normal units of the current system to merge
        them to the base and normal units given in argument.
        If not provided, name and description are overridden by empty strings.
        )r   r   r   r   r   )r   baser!   r   descriptionr"   r   r   r   r%   extend>   s   zUnitSystem.extendc                 C      | j S r   )r   r-   r   r   r%   get_dimension_systemK   s   zUnitSystem.get_dimension_systemc                    &   |   j}||v r|| S t |S r   )r5   _quantity_dimension_mapr   get_quantity_dimension)r   unitqdmr#   r   r%   r8   N      
z!UnitSystem.get_quantity_dimensionc                    r6   r   )r5   _quantity_scale_factorsr   get_quantity_scale_factor)r   r9   qsfmr#   r   r%   r=   T   r;   z$UnitSystem.get_quantity_scale_factorc                 C   s<   t | tr| S | tjvrtddttjtj|  S )NzDUnit system is not supported. Currentlysupported unit systems are {}r&   )
isinstancer   r   
ValueErrorformatr,   sorted)unit_systemr   r   r%   get_unit_systemZ   s   


zUnitSystem.get_unit_systemc                   C   s
   t jd S )NSI)r   r   r   r   r   r%   get_default_unit_systemi   s   
z"UnitSystem.get_default_unit_systemc                 C   s
   t | jS )zr
        Give the dimension of the system.

        That is return the number of units forming the basis.
        )lenr   r-   r   r   r%   dimm   s   
zUnitSystem.dimc                 C   s
   |   jS )zI
        Check if the underlying dimension system is consistent.
        )r5   is_consistentr-   r   r   r%   rI   v   s   
zUnitSystem.is_consistentreturnc                 C   r4   r   )r   r-   r   r   r%   r   ~   s   zUnitSystem.derived_unitsc                    s   ddl m} t|trt fdd|jD  S t|tr% |j|j S t|t	r2 |jd S t|t
rP |j}|jD ]\}}| ||  }q@|S t|trp fdd|jD }tdd |D rktjS |j| S t||r{ |jS tjS )Nr   r   c                       g | ]}  |qS r   get_dimensional_exprr)   ir-   r   r%   
<listcomp>       z3UnitSystem.get_dimensional_expr.<locals>.<listcomp>c                    rK   r   rL   r)   argr-   r   r%   rP      rQ   c                 s   s    | ]}|d kV  qdS )r   Nr   rN   r   r   r%   r+          z2UnitSystem.get_dimensional_expr.<locals>.<genexpr>)sympy.physics.unitsr   r?   r   argsr   rM   r1   expr   r   exprvariable_countr   allr	   Onefuncr8   r   )r   rX   r   rH   independentcountrV   r   r-   r%   rM      s(   






zUnitSystem.get_dimensional_exprc                    s  ddl m} t||r|j|jfS t|tr5d}td}|jD ]} |\}}||9 }||9 }q||fS t|t	r] |j
\}} |j\}	}
  |
rSd}
||	 ||	|
  fS t|tr |jd \}}|jdd D ]} |\}}  ||std|||||7 }qs||fS t|trĈ |jd \}}|jD ]\}} |\}}|||  }|||  }q||fS t|tr fdd|jD } fdd|D }|jd	d
 |D  g|R S t|trtj|fS |tdfS )zU
        Return tuple with scale factor expression and dimension expression.
        r   r   r   Nz,Dimension of "{}" is {}, but it should be {}c                    rK   r   )_collect_factor_and_dimensionrR   r-   r   r%   rP      rQ   z<UnitSystem._collect_factor_and_dimension.<locals>.<listcomp>c                    s.   g | ]}   |d  rtd n|d  qS )r   )r5   is_dimensionlessr   r(   r-   r   r%   rP      s   . c                 s   s    | ]}|d  V  qdS )r   Nr   )r)   fr   r   r%   r+      rT   z;UnitSystem._collect_factor_and_dimension.<locals>.<genexpr>)rU   r   r?   scale_factor	dimensionr   r   rV   r_   r   r1   rW   r5   r`   r   equivalent_dimsr@   rA   r   rY   r   r\   r	   r[   )r   rX   r   factorrc   rS   
arg_factorarg_dimrH   
exp_factorexp_dimaddendaddend_factor
addend_dimr]   r^   ifactoridimfdsdimsr   r-   r%   r_      sZ   










z(UnitSystem._collect_factor_and_dimensionc                 C   s   t tdd | jS )zK
        Return the units of the system that do not have a prefix.
        c                 S   s   | j  o| j S r   )is_prefixedis_physical_constant)ur   r   r%   <lambda>   s    z3UnitSystem.get_units_non_prefixed.<locals>.<lambda>)r   filterr   r-   r   r   r%   get_units_non_prefixed   s   z!UnitSystem.get_units_non_prefixed)__name__
__module____qualname____doc__r   tDictr   r   r   r.   r0   r3   r5   r8   r=   staticmethodrD   rF   propertyrH   rI   r   rM   r_   tSetrv   __classcell__r   r   r#   r%   r      s.    	&"



1r   N)rz   typingr   r{   r   r~   sympy.core.addr   sympy.core.functionr   r   sympy.core.mulr   sympy.core.powerr   sympy.core.singletonr	   sympy.physics.units.dimensionsr
   sympy.physics.units.quantitiesr   
dimensionsr   r   r   r   r   r%   <module>   s    