� ��gk����ddlmZddlmZmZmZmZmZddlm Z m Z ddl m Z ddl mZmZddlmZmZmZddlmZmZmZddlmZmZmZdd lmZdd lmZm Z dd l!m"Z"m#Z#m$Z$dd l%m&Z&m'Z'm(Z(dd l)m*Z*ddl+m,Z,ddl-m.Z.ddl/m0Z0m1Z1d%d�Z2d�Z3d&d�Z4d�Z5dd�d�Z6d'd�Z7d�Z8d(d�Z9d(d�Z:d(d�Z;d �Z<d!�Z=d"�Z>e=Z?e>Z@e<ZAd#�ZBd$�ZCdS))�)� defaultdict)�sympify�S�Mul� Derivative�Pow)�_unevaluated_Add�Add)� assumptions)�Factors� gcd_terms)�_mexpand� expand_mul�expand_power_base)� _keep_coeff�_unevaluated_Mul�_mulsort)�Rational�zoo�nan)�global_parameters)�ordered�default_sort_key)�Dummy�Wild�symbols)�exp�sqrt�log)�Abs)�gcd)� sqrtdenest)�iterable�siftNFTc � �����&�'�(�)�*�t|��}d�t���r�n�gD���d�}t�|d���\}}|r�tt |d�|D�������)�)fd��D���t |��)����|�����} d��)���D���*t| t��s| � �*��S�*fd �| ���D��S���t��} tj |��D]c} | j ��r| �vr�| js| �vr| �| ���2| j| j��d �} | �vr| �| ���dt%�fd �| D����} �t't)| ����z�| st |��|d ����S|� t*j}d�}d��'�'fd��(��(fd�}|r�|jr9|���pd�&|j����&�fd�|jD����&z}nZ|jr|j����fd�|jD���S|jr.t |j��d����}t;||j��Sd��D���d }�r7|���}|�!|j��rd }n|� ��}d�tj |��D��}tCt&��tDj#}}|D�]i}|�$d ���\}}t't)|����|z}�(fd�|D��}d}�D�]}t|tJ��r!|rt'tM|����}| }|||��}|��|j'stQd���|\}}}}|s\g} |D]M}!|!d� |!d }"n|!d |!dz}"| �)t;|!d|"�����NtU| �}#n ||��}#tW||��d ���}tW|#d ���}#||#�)|��n��||z }��kd�|���D��}|tDj#ur||tDj,<|�"|���D] \}$}%|%|z||$<��� �fd�|���D��}|r%td�|���D���S|S)a� Collect additive terms of an expression. Explanation =========== This function collects additive terms of an expression with respect to a list of expression up to powers with rational exponents. By the term symbol here are meant arbitrary expressions, which can contain powers, products, sums etc. In other words symbol is a pattern which will be searched for in the expression's terms. The input expression is not expanded by :func:`collect`, so user is expected to provide an expression in an appropriate form. This makes :func:`collect` more predictable as there is no magic happening behind the scenes. However, it is important to note, that powers of products are converted to products of powers using the :func:`~.expand_power_base` function. There are two possible types of output. First, if ``evaluate`` flag is set, this function will return an expression with collected terms or else it will return a dictionary with expressions up to rational powers as keys and collected coefficients as values. Examples ======== >>> from sympy import S, collect, expand, factor, Wild >>> from sympy.abc import a, b, c, x, y This function can collect symbolic coefficients in polynomials or rational expressions. It will manage to find all integer or rational powers of collection variable:: >>> collect(a*x**2 + b*x**2 + a*x - b*x + c, x) c + x**2*(a + b) + x*(a - b) The same result can be achieved in dictionary form:: >>> d = collect(a*x**2 + b*x**2 + a*x - b*x + c, x, evaluate=False) >>> d[x**2] a + b >>> d[x] a - b >>> d[S.One] c You can also work with multivariate polynomials. However, remember that this function is greedy so it will care only about a single symbol at time, in specification order:: >>> collect(x**2 + y*x**2 + x*y + y + a*y, [x, y]) x**2*(y + 1) + x*y + y*(a + 1) Also more complicated expressions can be used as patterns:: >>> from sympy import sin, log >>> collect(a*sin(2*x) + b*sin(2*x), sin(2*x)) (a + b)*sin(2*x) >>> collect(a*x*log(x) + b*(x*log(x)), x*log(x)) x*(a + b)*log(x) You can use wildcards in the pattern:: >>> w = Wild('w1') >>> collect(a*x**y - b*x**y, w**y) x**y*(a - b) It is also possible to work with symbolic powers, although it has more complicated behavior, because in this case power's base and symbolic part of the exponent are treated as a single symbol:: >>> collect(a*x**c + b*x**c, x) a*x**c + b*x**c >>> collect(a*x**c + b*x**c, x**c) x**c*(a + b) However if you incorporate rationals to the exponents, then you will get well known behavior:: >>> collect(a*x**(2*c) + b*x**(2*c), x**c) x**(2*c)*(a + b) Note also that all previously stated facts about :func:`collect` function apply to the exponential function, so you can get:: >>> from sympy import exp >>> collect(a*exp(2*x) + b*exp(2*x), exp(x)) (a + b)*exp(2*x) If you are interested only in collecting specific powers of some symbols then set ``exact`` flag to True:: >>> collect(a*x**7 + b*x**7, x, exact=True) a*x**7 + b*x**7 >>> collect(a*x**7 + b*x**7, x**7, exact=True) x**7*(a + b) If you want to collect on any object containing symbols, set ``exact`` to None: >>> collect(x*exp(x) + sin(x)*y + sin(x)*2 + 3*x, x, exact=None) x*exp(x) + 3*x + (y + 2)*sin(x) >>> collect(a*x*y + x*y + b*x + x, [x, y], exact=None) x*y*(a + 1) + x*(b + 1) You can also apply this function to differential equations, where derivatives of arbitrary order can be collected. Note that if you collect with respect to a function or a derivative of a function, all derivatives of that function will also be collected. Use ``exact=True`` to prevent this from happening:: >>> from sympy import Derivative as D, collect, Function >>> f = Function('f') (x) >>> collect(a*D(f,x) + b*D(f,x), D(f,x)) (a + b)*Derivative(f(x), x) >>> collect(a*D(D(f,x),x) + b*D(D(f,x),x), f) (a + b)*Derivative(f(x), (x, 2)) >>> collect(a*D(D(f,x),x) + b*D(D(f,x),x), D(f,x), exact=True) a*Derivative(f(x), (x, 2)) + b*Derivative(f(x), (x, 2)) >>> collect(a*D(f,x) + b*D(f,x) + a*f + b*f, f) (a + b)*f(x) + (a + b)*Derivative(f(x), x) Or you can even match both derivative order and exponent at the same time:: >>> collect(a*D(D(f,x),x)**2 + b*D(D(f,x),x)**2, D(f,x)) (a + b)*Derivative(f(x), (x, 2))**2 Finally, you can apply a function to each of the collected coefficients. For example you can factorize symbolic coefficients of polynomial:: >>> f = expand((x + a + 1)**3) >>> collect(f, x, factor) x**3 + 3*x**2*(a + 1) + 3*x*(a + 1)**2 + (a + 1)**3 .. note:: Arguments are expected to be in expanded form, so you might have to call :func:`~.expand` prior to calling this function. See Also ======== collect_const, collect_sqrt, rcollect c�,�g|]}t|����S�)r��.0�is �f/home/asafur/pinokio/api/open-webui.git/app/env/lib/python3.11/site-packages/sympy/simplify/radsimp.py� <listcomp>zcollect.<locals>.<listcomp>�s�� E� E� E�1�G�A�J�J� E� E� E�c�n�|jp.| jp&t|�t����S�N)� is_Symbol�bool�atomsr��xs r+�<lambda>zcollect.<locals>.<lambda>�s1��Q�[��a�R�N��d� ���� � �7�7�r-T)�binaryc �@�g|]}tdit|������S)r')rr r(s r+r,zcollect.<locals>.<listcomp>�s,��!K�!K�!K�a�%�"9�"9�+�a�.�.�"9�"9�!K�!K�!Kr-c�<��g|]}��||����Sr')�get)r)�s�repss �r+r,zcollect.<locals>.<listcomp>�s%���-�-�-�1�����A���-�-�-r-)�func�evaluate�exact�distribute_order_termc��i|]\}}||�� Sr'r'�r)�k�vs r+� <dictcomp>zcollect.<locals>.<dictcomp>�s��.�.�.���A��1�.�.�.r-c���i|]B\}}��||������|������CSr')r9�xreplace)r)rBrC�ureps �r+rDzcollect.<locals>.<dictcomp>�sU���,�,�,���1��H�H�Q��N�N�+�+�D�1�1�1�:�:�d�3C�3C�,�,�,r-N�c3�8�K�|]}|jo|j�vV��dSr/)�is_Pow�base)r)r*�symss �r+� <genexpr>zcollect.<locals>.<genexpr>�s0�����@�@�Q�Q�X�0�!�&�D�.�@�@�@�@�@�@r-Fc�\�g}|D]�\}}}}|�&|\}}|dkrt||��|dz }}|dk�|�H|tjur|�|���U|�t ||�����y|�t |||z������t |�S)NrrH)rr�One�appendrr)�terms�product�term�rat�sym�deriv�var�orders r+�make_expressionz collect.<locals>.make_expression�s�����%*� 3� 3� !�D�#�s�E�� �"� ��U��a�i�i�",�T�3�"7�"7����%�D��a�i�i��{��!�%�<�<��N�N�4�(�(�(�(��N�N�3�t�S�>�>�2�2�2�2����s�4��S��1�1�2�2�2�2��G�}�r-c��|j|jdd}}}|jdd�D]}||kr|dz }�td���t|t��rg|jd}|jD]}||krtd����||kr|j|t |j��z}}nnt|t���g||t |��ffS)NrrHz(Improve MV Derivative support in collect)�expr� variables�NotImplementedError� isinstancer�lenr)rVr[rUrXr:�s0s r+�parse_derivativez!collect.<locals>.parse_derivative�s��!�:�u��q�'9�1�5�c�������$� @� @�A��C�x�x��� ���)�>�@�@�@���z�*�*� ����"�B��^� D� D����7�7�-�B�D�D�D���S�y�y�"�i���T�^�1D�1D�)D�e������z�*�*� ��c�8�E�?�?�+�+�+r-c� ��tjd}}|d}}|jr�t|jt ��r�|j��\}}n|j}|jtjkrO|j}|jrtj|}}n�|j r*|� d���\}}t|��|}}n�|jj r|j}n�|j� ��\}}|j r||}}n�|j}n�t|t��rO|j}|jrtj|}}nU|j r*|� d���\}}t|��|}}n#t|t ��r�|��\}}||||fS)a�Parses expression expr and outputs tuple (sexpr, rat_expo, sym_expo, deriv) where: - sexpr is the base expression - rat_expo is the rational exponent that sexpr is raised to - sym_expo is the symbolic exponent that sexpr is raised to - deriv contains the derivatives of the expression For example, the output of x would be (x, 1, None, None) the output of 2**x would be (2, 1, x, None). NT)�rational) rrOrJr^rKr�Exp1r� is_Rational�is_Mul� as_coeff_Mul� is_Number) r[�rat_expo�sym_expo�sexprrV�arg�coeff�tailras �r+� parse_termzcollect.<locals>.parse_terms�����U�D�(���T�u�� �;� 2��$�)�Z�0�0� "�/�/�� �:�:� ��u�u�� ���y�A�F�"�"��h���?�7�&'�f�c�8�E�E��Z�7�"%�"2�"2�D�"2�"A�"A�K�E�4�&)�$�i�i��8�E����#� (��8���"�h�3�3�5�5� ��t��?�(�).��h�H�H�#�x�H�H� ��c� "� "� 2��(�C��� 3�"#�&�#�x����� 3�!�.�.��.�=�=� ��t�"%�d�)�)�U�x��� ��j� )� )� 2�+�+�D�1�1�L�E�5��h��%�/�/r-c�l��tj|��}t|��t|��krdS�fd�|D��}|dd�}gdd}}}|D]�\}}}}|jr |dkr|��t t|����D]�} || �� || \} } } } | �d}| �|���e| |ks| �]|�[| �|���F�dur| |z }|�|}n||krd}n || ks|| kr�t|�|| ��d|| <n��dS��d�|D��|||fS)z�Parse terms searching for a pattern. Terms is a list of tuples as returned by parse_terms; Pattern is an expression treated as a product of factors. Nc�&��g|] }�|����Sr'r')r)�elemros �r+r,z5collect.<locals>.parse_expression.<locals>.<listcomp>Ds#���<�<�<�D�z�z�$�'�'�<�<�<r-FrHTc��g|]}|�|��Sr'r')r)�_fs r+r,z5collect.<locals>.parse_expression.<locals>.<listcomp>~s��-�-�-�2�"�-�B�-�-�-r-)r� make_argsr_rh�range�matchrP)rQ�pattern�elems� common_expo� has_derivrr�e_rat�e_sym�e_ord�jrS�t_rat�t_sym�t_ord�expor>ros ��r+�parse_expressionz!collect.<locals>.parse_expression8s���� �-��(�(�� �u�:�:��G� � � $� $��4�<�<�<�<�G�<�<�<�G��!�!�!�H�E�,.��e� �;�E�-4�3 �3 �)��e�U�E��>��e�q�j�j�U�]���s�5�z�z�*�*�- �- �A��Q�x�'� �05�a��-�D�%��� �(�$(� �� � �4�(�(�4�"�e�^�^�u�/@�!�-�!�K�K��.�.�:� �E�>�>�$)�5�=�D�*�2�.2� � � $/�$�#6�#6�23�K�� %��~�~��%��� (�� � �U�1�X�.�.�.�#'��a����� �4�4� � .�-��-�-�-�u�k�9�L� Lr-rc �D��g|]}|�k�t|��d������S�T��collect)r)�ar?r>r<�orLs �����r+r,zcollect.<locals>.<listcomp>�s<���2�2�2��!�q�&�&��A�t�T�4��8M�N�N�*0�&�&r-c �8��g|]}t|��d������Sr�r�)r)rSr?r>r<rLs ����r+r,zcollect.<locals>.<listcomp>�s<���'�'�'����d�D�$��7L�M�M�'�'�'r-c�0�g|]}t|d�����S�F��deep�rr(s r+r,zcollect.<locals>.<listcomp>�s&�� ;� ;� ;�� �a�e� ,� ,� ,� ;� ;� ;r-c�0�g|]}t|d�����Sr�r�r(s r+r,zcollect.<locals>.<listcomp>�s&�� K� K� K�!� �q�u� -� -� -� K� K� Kr-)�split_1c�&��g|] }�|����Sr'r')r)r*ros �r+r,zcollect.<locals>.<listcomp>�s!���-�-�-�1���A���-�-�-r-z%Can not collect noncommutative symbol�r�c�(�i|]\}}|t|���Sr')r rAs r+rDzcollect.<locals>.<dictcomp>�s"��:�:�:���1��C��G�:�:�:r-c�.��i|]\}}|�|����Sr'r')r)�key�valr<s �r+rDzcollect.<locals>.<dictcomp>�s4���>�>�>�'�s�C�C���c���>�>�>r-c��g|] \}}||z�� Sr'r')r)r�r�s r+r,zcollect.<locals>.<listcomp>�s ��?�?�?���c�S��W�?�?�?r-)-rr#r$�dict�zipr��subs�itemsr^rF�setr ru�has_freerf�add� _new_rawargs� as_coeff_mul�all�listrrr=�is_Add�getOr<�argsrJrKrr�has�removeOrr�Zero�args_cncr�reversed�is_commutative�AttributeErrorrPrrrO)+r[rLr<r=r>r?�cond�_�nonsyms�rv�_symsr*�g�simplerYr��b� order_term�summa� collected�dislikedrR�c�ncr�rQ� small_first�symbol�resultryrzr{�margsrr�e�indexr�r�r�raror;rGs+ `` `` @@@@@r+r�r�s������������l �4�=�=�D� E� E��$���!C���d�V� E� E� E�D� � �D��d�D��.�.�.�J�A�w�� ,��C��!K�!K�7�!K�!K�!K�L�L�M�M��-�-�-�-��-�-�-�� �T�Y�Y�t�_�_�d����"7�9�9�9��/�.������.�.�.���"�d�#�#� ,��;�;�t�$�$� $�,�,�,�,� "��� � �,�,�,� ,� �}�������t�$�$� !� !�A��1�:�t�$� ��T� � ���8� !��� � �� � �!� � � � �#�A�N�N�A�N�D�$9�!�$<�=���D�=�=��I�I�a�L�L�L���@�@�@�@�%�@�@�@�@�@���d�7�5�>�>�*�*�*��� 9��4�����"7�9�9�9� 9���$�-�����(,�,�,�600�00�00�00�00�dFM�FM�FM�FM�FM�FM�P� $� �;� $�� � � � � �q�A��4�9�2�2�2�2�2�2�2�2�!�Y�2�2�2�3�56�7�D�D��[� $��4�9�'�'�'�'�'�'�'� �I�'�'�'�(� (��[� $��� �4��t�U�4I�K�K�A��q�$�(�#�#� #� ;� ;�d� ;� ;� ;�D��J��&��Y�Y�[�[� � � !��z�~�t�$� &�!� � ��|�|�~�~�� K� K�s�}�T�7J�7J� K� K� K�E�%�d�+�+�Q�V�x�I��% �% ��� � �� �/�/���2��G�A�J�J���"�$��-�-�-�-��-�-�-��� �� � �F��&�*�-�-� .�+� .��X�e�_�_�-�-��"-�o� �%�%�e�V�4�4�F��!��,�R�(�)P�Q�Q�Q�7=�4��u�k�9�!� 3��E� %�6�6����7�?� $�Q��A�A� $�Q���Q���A�� � �S��a��!�_�_�5�5�5�5���K�E�E�+�O�E�2�2�E�)�/�/�%�*@�*@�u�M�M�M��)�%�e�<�<�<���%� �'�'��.�.�.���-"�2 �� �H��:�:� ���(9�(9�:�:�:�I��q�v���#� �!�%����!���)�)� .� .�H�C�� �:�-�I�c�N�N� ��>�>�>�>�+4�?�?�+<�+<�>�>�>� ����?�?�Y�_�_�->�->�?�?�?�@�@��r-c���|js |j��s|S|j�fd�|jD���}|jrt |���S|S)aQ Recursively collect sums in an expression. Examples ======== >>> from sympy.simplify import rcollect >>> from sympy.abc import x, y >>> expr = (x**2*y + x*y + x + y)/(x + y) >>> rcollect(expr, y) (x + y*(x**2 + x + 1))/(x + y) See Also ======== collect, collect_const, collect_sqrt c�*��g|]}t|g��R���Sr')�rcollect)r)rl�varss �r+r,zrcollect.<locals>.<listcomp>�s)���J�J�J���� 4�t� 4� 4� 4�J�J�Jr-)�is_Atomr�� __class__r�r�r�)r[r�s `r+r�r��sg���( �|��8�4�8�T�?��� ��t�~�J�J�J�J�� �J�J�J�K�� �;� ��4��&�&� &��Kr-c�4�|� tj}|���\}}t��}t j|��D]l}|���dD]O}|jrF|jr|j j r|j j dks|tj ur|�|���P�mt|g|�Rddi�}||k}|s�d}t!t#t j|������} t%| ��D]i\} }|���\} } | D]:} | jr| j j r| j j dks| tj ur|dz }n�;| | xx|zcc<�j|s |s t | �g} t'| ��|fS||zS)aLReturn expr with terms having common square roots collected together. If ``evaluate`` is False a count indicating the number of sqrt-containing terms will be returned and, if non-zero, the terms of the Add will be returned, else the expression itself will be returned as a single term. If ``evaluate`` is True, the expression with any collected terms will be returned. Note: since I = sqrt(-1), it is collected, too. Examples ======== >>> from sympy import sqrt >>> from sympy.simplify.radsimp import collect_sqrt >>> from sympy.abc import a, b >>> r2, r3, r5 = [sqrt(i) for i in [2, 3, 5]] >>> collect_sqrt(a*r2 + b*r2) sqrt(2)*(a + b) >>> collect_sqrt(a*r2 + b*r2 + a*r3 + b*r3) sqrt(2)*(a + b) + sqrt(3)*(a + b) >>> collect_sqrt(a*r2 + b*r2 + a*r3 + b*r5) sqrt(3)*a + sqrt(5)*b + sqrt(2)*(a + b) If evaluate is False then the arguments will be sorted and returned as a list and a count of the number of sqrt-containing terms will be returned: >>> collect_sqrt(a*r2 + b*r2 + a*r3 + b*r5, evaluate=False) ((sqrt(3)*a, sqrt(5)*b, sqrt(2)*(a + b)), 3) >>> collect_sqrt(a*sqrt(2) + b, evaluate=False) ((b, sqrt(2)*a), 1) >>> collect_sqrt(a + b, evaluate=False) ((a + b,), 0) See Also ======== collect, collect_const, rcollect Nrr��NumbersFrH)rr=�as_content_primitiver�r rur�� is_numberrJrre�qr� ImaginaryUnitr�� collect_constr�r� enumerate�tuple)r[r=rmr�r��m�d�hit�nradr�r*r�r��cis r+� collect_sqrtr��s���R��$�-���+�+�-�-�K�E�4� �5�5�D� �]�4� � ���������a�� � �A��{� ��H� �!"��!2� �78�u�w�!�|�|����(�(����� � � ��  � �d�1�T�1�1�1�5�1�1�A� �!�)�C� �!����G�C�M�!�,�,�-�-�.�.���d�O�O� � �D�A�q��J�J�L�L�E�A�r�� � ���9����!3�����A� � ��a�o�-�-��A�I�D��E�.� ��G�G�G�u� �G�G�G�G�� �t� ���J�<�D��T�{�{�D� � � ��7�Nr-c�n��d��|�d��fd����d��fd���S)aLReturn ``expr`` with arguments of multiple Abs in a term collected under a single instance. Examples ======== >>> from sympy.simplify.radsimp import collect_abs >>> from sympy.abc import x >>> collect_abs(abs(x + 1)/abs(x**2 - 1)) Abs((x + 1)/(x**2 - 1)) >>> collect_abs(abs(1/x)) Abs(1/x) c��|���\}}g}g}|D]�}t|t��r!|�|jd���8t|t ��rTt|jt��r:|jjr.|�|jjd|jz����|�|����t|��dkrtd�|D����s|St|�}t|��}|g}|� |��|� t��s|� |��t|�St|t��st|d���}||d<t|��|� |��tj|| ���S)Nrr�c3�XK�|]%}t|t���|jjV��&dSr/)r^rr� is_negativer(s r+rMz,collect_abs.<locals>._abs.<locals>.<genexpr>`s6����S�S�a� �1�c�@R�@R�S��� 1�S�S�S�S�S�Sr-F�r=)r�)r�r^r rPr�rrKr�is_realr_�anyr�extendr�r� _from_args) �mulr�r�r�r�r*�absarg�Ar�s r+�_abszcollect_abs.<locals>._absUs����l�l�n�n�e�a�� �a� �a����!� ��3� � � ��h�h�q�v�a�y�!�!�!�!��!�S�!�!� �j����&=�&=� �!�%�-� ��h�h�q�v�{�1�~�q�u�,�-�-�-�-��h�h�q�k�k�k�k� �Q���!���C�S�S�1�S�S�S�S�S���*��A�w�f� �f�+�+�a��S�d� �k�k�!�n�n�n� �U�U�3�Z�Z�� �+�+�b�/�/�/��d�� � ��3� � �*��&�5�)�)�)�!��d�1�g��t�n�n�n� �k�k�"�o�o�o� �^�D�R�� 8� 8� 8�8r-c�,�t|t��Sr/)r^rr3s r+r5zcollect_abs.<locals>.<lambda>rs��*�Q��$�$�r-c����|��Sr/r'�r4r�s �r+r5zcollect_abs.<locals>.<lambda>ss���$�$�q�'�'�r-c�,�t|t��Sr/)r^rr3s r+r5zcollect_abs.<locals>.<lambda>ts��j��C�(�(�r-c����|��Sr/r'r�s �r+r5zcollect_abs.<locals>.<lambda>us���d�d�1�g�g�r-)�replace)r[r�s @r+� collect_absr�Gs]���9�9�9�8 �<�<�$�$����� � �"�7� (� (� � � � ���r-)r�c ����|js|Sd}|sNd}t��}|jD]5}tj|��D]}|jr|�|����6nt|��}|s d�|D��}tt|����}|D�]�}tt��}t|��}tj|��D]�}t|��} | � |��\} } | jrj| j����| j�t#��fd��D����s.||�| �������|t(j�|����g} d} d}t|��D]�}||}|t(jur| �|���.t/|��dkr)t|�}d} |r||kr|�|��n|d}|r6|jr/|jr(| �t3||d�����d}��| �||z����| r|r t5| �}n t| �}|jsn���|S)a�A non-greedy collection of terms with similar number coefficients in an Add expr. If ``vars`` is given then only those constants will be targeted. Although any Number can also be targeted, if this is not desired set ``Numbers=False`` and no Float or Rational will be collected. Parameters ========== expr : SymPy expression This parameter defines the expression the expression from which terms with similar coefficients are to be collected. A non-Add expression is returned as it is. vars : variable length collection of Numbers, optional Specifies the constants to target for collection. Can be multiple in number. Numbers : bool Specifies to target all instance of :class:`sympy.core.numbers.Number` class. If ``Numbers=False``, then no Float or Rational will be collected. Returns ======= expr : Expr Returns an expression with similar coefficient terms collected. Examples ======== >>> from sympy import sqrt >>> from sympy.abc import s, x, y, z >>> from sympy.simplify.radsimp import collect_const >>> collect_const(sqrt(3) + sqrt(3)*(1 + sqrt(2))) sqrt(3)*(sqrt(2) + 2) >>> collect_const(sqrt(3)*s + sqrt(7)*s + sqrt(3) + sqrt(7)) (sqrt(3) + sqrt(7))*(s + 1) >>> s = sqrt(2) + 2 >>> collect_const(sqrt(3)*s + sqrt(3) + sqrt(7)*s + sqrt(7)) (sqrt(2) + 3)*(sqrt(3) + sqrt(7)) >>> collect_const(sqrt(3)*s + sqrt(3) + sqrt(7)*s + sqrt(7), sqrt(3)) sqrt(7) + sqrt(3)*(sqrt(2) + 3) + sqrt(7)*(sqrt(2) + 2) The collection is sign-sensitive, giving higher precedence to the unsigned values: >>> collect_const(x - y - z) x - (y + z) >>> collect_const(-y - z) -(y + z) >>> collect_const(2*x - 2*y - 2*z, 2) 2*(x - y - z) >>> collect_const(2*x - 2*y - 2*z, -2) 2*x - 2*(y + z) See Also ======== collect, collect_sqrt, rcollect FTc� �g|] }|j� |�� Sr')rh)r)rCs r+r,z!collect_const.<locals>.<listcomp>�s��3�3�3�a�q�{�3��3�3�3r-c3�V�K�|]#}|�vo�|jo �|j V��$dSr/)� is_Integer)r)rB�fnow�fwass ��r+rMz collect_const.<locals>.<genexpr>�s^�����:�:�/0���9�+��a��);�+��Q��*�A+�:�:�:�:�:�:r-rHr)�sign)r�r�r�rrur�r�rr�rrr r �div�is_one�factors�copyr�rP�as_exprrrOr�r_rhrr )r[r�r��recurser�r�rCrQ�Fv�fr��rr�r��unevalrBr�r�s @@r+r�r�xs�����| �;��� ��G� �����u�u���� � �A��]�1�%�%� � ���;� ��H�H�Q�K�K�K�� � � �t�}�}�� �4�3�3�4�3�3�3�� ��� � � � �D� �3�3���D�!�!�� �Q�Z�Z����t�$�$� #� #�A��� � �A��5�5��9�9�D�A�q��x� � �y�~�~�'�'���y���:�:�:�:�:�48�:�:�:�:�:���!�H�O�O�A�I�I�K�K�0�0�0�� �!�%�L� � �� "� "� "� "����������� !� !�A��a��A��A�E�z�z�� � �A������1�v�v��z�z���G�����#�q�D�y�y��K�K��N�N�N���a�D�� � !�1�;� !�1�8� !�� � �K��1�4�8�8�8�9�9�9����� � �A�a�C� � � � � � �� "�'��.����D�z���;� ���� �Kr-�c ����� � � ���ddlm�td����fd�� d �fd� � � � � ��fd�� |���\}}|���}t |��}t � |����\}}|||fk�rG|js�||f}�|d���}�|d���}tt|d |z ����}td �|j � ��D���}t |��\}}|||fkr|\}}t|��}|j s|j r�t tt|d |z ������\} } | j s*| ���|���kr;�fd �| | fD��\}}|jr!|jdj r|j|j�}|t|d |z ��zS) a Rationalize the denominator by removing square roots. Explanation =========== The expression returned from radsimp must be used with caution since if the denominator contains symbols, it will be possible to make substitutions that violate the assumptions of the simplification process: that for a denominator matching a + b*sqrt(c), a != +/-b*sqrt(c). (If there are no symbols, this assumptions is made valid by collecting terms of sqrt(c) so the match variable ``a`` does not contain ``sqrt(c)``.) If you do not want the simplification to occur for symbolic denominators, set ``symbolic`` to False. If there are more than ``max_terms`` radical terms then the expression is returned unchanged. Examples ======== >>> from sympy import radsimp, sqrt, Symbol, pprint >>> from sympy import factor_terms, fraction, signsimp >>> from sympy.simplify.radsimp import collect_sqrt >>> from sympy.abc import a, b, c >>> radsimp(1/(2 + sqrt(2))) (2 - sqrt(2))/2 >>> x,y = map(Symbol, 'xy') >>> e = ((2 + 2*sqrt(2))*x + (2 + sqrt(8))*y)/(2 + sqrt(2)) >>> radsimp(e) sqrt(2)*(x + y) No simplification beyond removal of the gcd is done. One might want to polish the result a little, however, by collecting square root terms: >>> r2 = sqrt(2) >>> r5 = sqrt(5) >>> ans = radsimp(1/(y*r2 + x*r2 + a*r5 + b*r5)); pprint(ans) ___ ___ ___ ___ \/ 5 *a + \/ 5 *b - \/ 2 *x - \/ 2 *y ------------------------------------------ 2 2 2 2 5*a + 10*a*b + 5*b - 2*x - 4*x*y - 2*y >>> n, d = fraction(ans) >>> pprint(factor_terms(signsimp(collect_sqrt(n))/d, radical=True)) ___ ___ \/ 5 *(a + b) - \/ 2 *(x + y) ------------------------------------------ 2 2 2 2 5*a + 10*a*b + 5*b - 2*x - 4*x*y - 2*y If radicals in the denominator cannot be removed or there is no denominator, the original expression will be returned. >>> radsimp(sqrt(2)*x + sqrt(2)) sqrt(2)*x + sqrt(2) Results with symbols will not always be valid for all substitutions: >>> eq = 1/(a + b*sqrt(c)) >>> eq.subs(a, b*sqrt(c)) 1/(2*b*sqrt(c)) >>> radsimp(eq).subs(a, b*sqrt(c)) nan If ``symbolic=False``, symbolic denominators will not be transformed (but numeric denominators will still be processed): >>> radsimp(eq, symbolic=False) 1/(a + b*sqrt(c)) r)�signsimpza:d A:Dc���� \}}}}}}}}t|��dkrpttt||||gd�|D��������} t |��|zt |��|zz �| ��St|��dkr�ttt||||||gd�|D��������} t |��|zt |��|zzt |��|zz dt |��zt |��z|z|z||dzzz ||dzzz ||dzzzz�| ��St|��dk�r ttt||||||||gd�|D��������} t |��|zt |��|zzt |��|zz t |��|zz dt |��zt |��z|z|z||dzzz ||dzzz dt |��zt |��z|z|zz ||dzzz||dzzzzdt |��zt |��zt |��zt |��z|z|z|z|z|dz|dzzzd|z|z|dzz|dzzz d|z|z|dzz|dzzz d|z|z|dzz|dzzz |dz|dzzzd|z|z|dzz|dzzz d|z|z|dzz|dzzz |dz|dzzzd|z|z|dzz|dzzz |dz|dzzzz�| ��St|��dkrt |d d ��St �) Nr�c��g|] }|D]}|��� Sr'r'�r)r*rs r+r,z)radsimp.<locals>._num.<locals>.<listcomp>Ts%��/M�/M�/M�a�1�/M�/M�a��/M�/M�/M�/Mr-�c��g|] }|D]}|��� Sr'r'rs r+r,z)radsimp.<locals>._num.<locals>.<listcomp>Xs&��5S�5S�5S�A�QR�5S�5S�A�a�5S�5S�5S�5Sr-r�c��g|] }|D]}|��� Sr'r'rs r+r,z)radsimp.<locals>._num.<locals>.<listcomp>]s'��;Y�;Y�;Y�!�WX�;Y�;Y�RS�A�;Y�;Y�;Y�;Yr-i����rHr)r_r�r�r�rrFr]) �rtermsr�r�r�r�r��B�C�Dr;rLs �r+�_numzradsimp.<locals>._numOs#���"&���1�a��A�q�!�Q� �v�;�;�!� � ���S�!�Q��1��/M�/M�6�/M�/M�/M�N�N�O�O�P�P�D� ��G�G�A�I��Q���� � !�8�8�D�>�>� 2� �v�;�;�!� � ���S�!�Q��1�a��!3�5S�5S��5S�5S�5S�T�T�U�U�V�V�D� �!�W�W�Q�Y��a����� "�T�!�W�W�Q�Y� .��4��7�7��4��7�7�1B�1�1D�Q�1F��1�a�4��1O� �a��d�F�2��q�!�t�V�2� �&�h�t�n�n� -���[�[�A� � ���S�!�Q��1�a��A�q�!9�;Y�;Y�v�;Y�;Y�;Y�Z�Z�[�[�\�\�D��!�W�W�Q�Y��a�����*�T�!�W�W�Q�Y�6��a�����B�Q�t�A�w�w�Y�t�TU�w�w�EV�WX�EX�YZ�EZ��A�q�D�&�F��Q��T�6�F"�$%�d�1�g�g�I�d�1�g�g�$5�a�$7��$9�F:�<=�a��d�F�FC��!�Q�$��F���D��G�G��D��G�G�+�D��G�G�3�D��G�G�;�A�=�a�?��A�!�C�a��d�1�a�4�i�O��!��A��a��d� �1�a�4�� �"#�A�#�a�%��1��*�Q��T�/�2�45�a�C��E�!�Q�$�J�q�!�t�O�D�FG��d�1�a�4�i�P��!��A��a��d� �1�a�4�� �"#�A�#�a�%��1��*�Q��T�/�2�45�q�D��A��I�>�@A�!��A��a��d� �1�a�4��P��1��Q��T� ��� %�H�T�N�N�  +� ��[�[�A� � ���q� �!� �%�%� %�%� %r-Fc���|jsdS|j}|jr |jdks�rt |��dkrdS|rHd}|jr|j}n�rt |��}|jr|}|dkrt |d��jrdSdS)NFr�TrH)rJrrer��denomr�r)r��log2r�r��symbolics �r+�ispow2zradsimp.<locals>.ispow2is�����x� ��5� �E�� �=� �Q�S�A�X�X��X�e�A�h�h�!�m�m��4� � ��A��}� ��C���� ��!�H�H���<���A��A�v�v�#�a��)�)�.�v��t��ur-c����ddlm}t|��\}}|js|jr |jr|S|js7|j�fd�|jD���}t |�d|z ����S|tjurt |�d|z ����S|j rt �fd�|jD���S�s |j r|S�|��rKtt|j ����t|j��z}||kr�d|z ��Sn:|jr3|jjs |j jr�d|j z ��|jzS|js)�|��sd|j�fd�|jD���z Sd}t)|��}|jrd|z S|jr,||��}|jr|�|��rd|z S t1t2��}t5j|��D]�}g} g} t9j|��D]�} �| d���r@| �| jtjur| j n| j d | jzz���O| tjur | �tj ���}| �| ����|tCtE| �����t9| �����t3tEt3|�#��������} d �| D��} tI| ��| ddtjurdndz } | dkrn�| �krd }n�tI| ��d kr[tKd �| D����r?tMtjt5j'd�| D������\}}||z}nd }nwddl(m)}m*}|�| ����}||z}||z}|t)|������}|�+tj,tZt\��r|S|jrn��||s|St |d|z ��S)Nr)� nsimplifyc�&��g|] }�|����Sr'r'�r)r��handles �r+r,z+radsimp.<locals>.handle.<locals>.<listcomp>�s!���3�3�3�q������3�3�3r-rHc�,��g|]}�d|z ����S�rHr')r)r�rs �r+r,z+radsimp.<locals>.handle.<locals>.<listcomp>�s%���%B�%B�%B�a�f�f�Q�q�S�k�k�%B�%B�%Br-c�&��g|] }�|����Sr'r'rs �r+r,z+radsimp.<locals>.handle.<locals>.<listcomp>�s!���8�8�8�A�f�f�Q�i�i�8�8�8r-T)r r�c�8�g|]\}}t|�t|�f��Sr')rr rs r+r,z+radsimp.<locals>.handle.<locals>.<listcomp>�s)��<�<�<�T�Q��s�A�w��Q��(�<�<�<r-Fr�c3�>K�|]\}}|jo |dzjV��dS)r�N)r�re�r)r4�ys r+rMz*radsimp.<locals>.handle.<locals>.<genexpr>�s4����N�N�t�q�!�q�|�:��A��(:�N�N�N�N�N�Nr-c�8�g|]\}}t|��|z��Sr')rrs r+r,z+radsimp.<locals>.handle.<locals>.<listcomp>�s&��6�6�6�t�q�!��a�����6�6�6r-)�powsimp� powdenest)�force)/�sympy.simplify.simplifyr�fractionr�r<r�rrrOrf� free_symbolsr"rrK�numerrrJ� is_integer� is_positiver�rr�rh�equalsrr�r rurrP�Halfr�� NegativeOner�rr�r_r��rad_rationalizer��sympy.simplify.powsimprrr�r�rr)r[r�nr��d2�keep�_dr�r��p2�otherr*rr��ndrr�numr rr� max_termsrs �����r+rzradsimp.<locals>.handle{s���� 6�5�5�5�5�5���~�~���1� �<� D�A�I� D�!�)� D��K��� D����3�3�3�3�A�F�3�3�3�4�A�#�A�v�v�a��c�{�{�3�3� 3� �a�e�^�^�#�A�v�v�a��c�{�{�3�3� 3� �X� D�#�%B�%B�%B�%B�1�6�%B�%B�%B�C� C�� �A�N� ��K� �6�!�9�9� +��D���L�L�)�)�5���<�<�7�B��Q�w�w��v�a��d�|�|�#�� �X� +�1�5�+� +�q�v�/A� +��6�!�A�F�(�#�#�Q�U�*� *��� :�F�F�1�I�I� :��V�Q�V�8�8�8�8���8�8�8�9�9� 9��� �Q�K�K�� �9� ��Q�3�J� �;� ���1���B��|� �� � �!� � � ���t� �0 �#�D�)�)�I��]�1�%�%� B� B��������q�)�)�(�(�A��v�a�d�+�+�+�(�� � �A�E�Q�V�O�O�!�&�&���!�A�E�'�AR�S�S�S�S��a�o�-�-�� � �!�-�0�0�0�0�� � �Q������%��� � �,�,�-�4�4�S�%�[�A�A�A�A��'�$�y���'8�'8�"9�"9�:�:�;�;�F�<�<�V�<�<�<�F��v�;�;�v�a�y��|�q�u�'<�'<�!�!�!�D�D��a�x�x��� �!�!� ����6�{�{�Q����N�N�v�N�N�N�N�N�!�+�A�E�3�>�6�6�v�6�6�6�48�48�9�9�E�B����G�A�A�!�D�� A� A� A� A� A� A� A� A��'�$�$�v�,�,�'�'�C� ��H�A� ��H�A�� �(�1�+�+�X�6�6�6�A��u�u�Q�V�S�#�&�&� �� ��y� ��a0 �d� ��K���1�Q�3�'�'�'r-r�rHc��g|] \}}||z�� Sr'r'rAs r+r,zradsimp.<locals>.<listcomp>�s ��"F�"F�"F�D�A�q�1�a�4�"F�"F�"Fr-c�&��g|] }�|����Sr'r')r)r*r�s �r+r,zradsimp.<locals>.<listcomp>�s!���6�6�6����� � �6�6�6r-�F)r r�r� as_coeff_Add�normalr!r�r rr�r�rrhr�r � count_opsrfr�r<)r[rr3rm�oldr+r��was�u�n2r,r rrr�rLs `` @@@@@r+�radsimpr>s]���������X1�0�0�0�0�0� �9� � �D�&�&�&�&�&�4������$g(�g(�g(�g(�g(�g(�g(�g(�g(�R�#�#�%�%�K�E�4� �;�;�=�=�D� �4�.�.�C� �F�F�4�L�L� !� !�D�A�q� �q�!�f�}�}��y� ��a�&�C����U�+�+�+�A����U�+�+�+�A��(��A�a�C�0�0�1�1�A� �"F�"F�A�I�O�O�4E�4E�"F�"F�"F�G�A��A�;�;�D�A�q��q�!�f�}�}����1� �q�M�M�� �;� (�!�(� (��i�(8��A�a�C�(@�(@�A�A�B�B�F�B���|� (�� � ���!�+�+�-�-� ?� ?�6�6�6�6�b�"�X�6�6�6���1��8�(���q� � 3�(�������A� �#�A�q��s�+�+� +�+r-c���|js||fSt|��\}}}|t|��z}t||z |z��}t|dz|dzz ��}t ||��S)a\ Rationalize ``num/den`` by removing square roots in the denominator; num and den are sum of terms whose squares are positive rationals. Examples ======== >>> from sympy import sqrt >>> from sympy.simplify.radsimp import rad_rationalize >>> rad_rationalize(sqrt(3), 1 + sqrt(2)/3) (-sqrt(3) + sqrt(6)/3, -7/9) r�)r�� split_surdsrrr))r2�denr�r�r�s r+r)r)�sw�� �:���C�x���#���G�A�q�!� �$�q�'�'� �A� �A��E�3�;� � �C� �1�a�4�!�Q�$�;� � �C� �3�� $� $�$r-c��t|��}gg}}tj|��D�]�}|j�r[|jst |t ���r>|���\}}|jr�|tj ur|� |���j|rO|� ��r%|� t|| ������|� |����|� t|| ������|jr|� |����|sP|jrI|���\}}|dkr|� |��|� |����O|� |����f|jrH|jsA|jdkr|� |j��|� |j�����|� |�����t|d| i�t|d| i�fS)a�Returns a pair with expression's numerator and denominator. If the given expression is not a fraction then this function will return the tuple (expr, 1). This function will not make any attempt to simplify nested fractions or to do any term rewriting at all. If only one of the numerator/denominator pair is needed then use numer(expr) or denom(expr) functions respectively. >>> from sympy import fraction, Rational, Symbol >>> from sympy.abc import x, y >>> fraction(x/y) (x, y) >>> fraction(x) (x, 1) >>> fraction(1/y**2) (1, y**2) >>> fraction(x*y/2) (x*y, 2) >>> fraction(Rational(1, 2)) (1, 2) This function will also work fine with assumptions: >>> k = Symbol('k', negative=True) >>> fraction(x * y**k) (x, y**(-k)) If we know nothing about sign of some exponent and ``exact`` flag is unset, then the exponent's structure will be analyzed and pretty fraction will be returned: >>> from sympy import exp, Mul >>> fraction(2*x**(-y)) (2, x**y) >>> fraction(exp(-x)) (1, exp(x)) >>> fraction(exp(-x), exact=True) (exp(-x), 1) The ``exact`` flag will also keep any unevaluated Muls from being evaluated: >>> u = Mul(2, x + 1, evaluate=False) >>> fraction(u) (2*x + 2, 1) >>> fraction(u, exact=True) (2*(x + 1), 1) rHr=)rrrur�rJr^r� as_base_expr�rr(rP� is_constantrr%rf�as_numer_denomrer��pr�) r[r>r#r rSr��exr+r�s r+r!r!s ��p �4�=�=�D��r�5�E�� �d�#�#���� � � �D�K� �:�d�C�3H�3H� ��$�$�&�&�E�A�r��~� #����&�&��L�L��O�O�O�O��.��~�~�'�'�+�� � �S��R�C�[�[�1�1�1�1�� � �T�*�*�*�*��L�L��Q�����-�-�-�-��� #�� � �T�"�"�"�"�� #�r�y� #��*�*�,�,���1���6�6��L�L��O�O�O�� � �Q������ � �T�"�"�"�"� � � �d�o� ��v��{�{�� � �T�V�$�$�$� �L�L��� � � � � �L�L�� � � � � �� *�E� � *� *�C��,K�U��,K�,K� K�Kr-c�0�t||���dS)N�r>r�r!�r[r>s r+r#r#n��� �D�� &� &� &�q� )�)r-c�0�t||���dS)NrIrHrJrKs r+r r rrLr-c � �|jdddi|��S)N�fracTr')�expand)r[�hintss r+�fraction_expandrRvs�� �4�;� *� *�D� *�E� *� *�*r-c �v�t||�dd�����\}}|jdddi|��|z S)Nr>FrIr#Tr'�r!r9rP�r[rQr�r�s r+� numer_expandrVzsH�� �D�� � �'�5� 9� 9� :� :� :�D�A�q� �1�8� (� (�$� (�%� (� (�1� ,�,r-c �v�t||�dd�����\}}||jdddi|��z S)Nr>FrIr Tr'rTrUs r+� denom_expandrX�sH�� �D�� � �'�5� 9� 9� :� :� :�D�A�q� �x�q�x�,�,�d�,�e�,�,� ,�,r-c���t|jt���}d�|D��}d�|D��}|�t���t |�\�}}�}|s?t |��dkr,�fd�|D��}d�|D��}t |�\}}}�|z}gg} } |D]�\} } | jrb| jtj krM| j } | |vr)| � | t| |z ��z���U| � | | z���n| � | | z����t| �}t| �}|||fS)a� Split an expression with terms whose squares are positive rationals into a sum of terms whose surds squared have gcd equal to g and a sum of terms with surds squared prime with g. Examples ======== >>> from sympy import sqrt >>> from sympy.simplify.radsimp import split_surds >>> split_surds(3*sqrt(3) + sqrt(5)/7 + sqrt(6) + sqrt(10) + sqrt(15)) (3, sqrt(2) + sqrt(5) + 3, sqrt(5)/7 + sqrt(10)) )r�c�6�g|]}|�����Sr')rg�r)r4s r+r,zsplit_surds.<locals>.<listcomp>�s"��1�1�1�q�!�.�.�"�"�1�1�1r-c�>�g|]}|dj�|ddz��S)rHr�)rJr[s r+r,zsplit_surds.<locals>.<listcomp>�s+�� 8� 8� 8��A�a�D�K� 8�Q�q�T�1�W� 8� 8� 8r-r�c���g|]}|�z ��Sr'r')r)r4r�s �r+r,zsplit_surds.<locals>.<listcomp>�s������q�q��s���r-c��g|] }|dk�|�� Srr'r[s r+r,zsplit_surds.<locals>.<listcomp>�s��(�(�(�Q��a���q���r-)�sortedr�r�sort� _split_gcdr_rJrrr'rKrPrr )r[r�� coeff_muls�surds�b1�b2�g2�b1n�g1�a1v�a2vr�r:�s1r�r�r�s @r+r@r@�sq��� �$�)�!1� 2� 2� 2�D�1�1�D�1�1�1�J� 8� 8�j� 8� 8� 8�E� �J�J�#�J�$�$�$��E�"�I�A�r�2� �B� ��#�b�'�'�Q�,�,�����B�����(�(�#�(�(�(�� �#�&� ��C�� �r�T���2��C������1� �8� ���������B��R�x�x�� � �1�T�"�R�%�[�[�=�)�)�)�)�� � �1�Q�3����� �J�J�q��s�O�O�O�O� �S� �A� �S� �A� �q�!�8�Or-c���|d}|g}g}|dd�D]E}t||��}|dkr|�|���.|}|�|���F|||fS)a` Split the list of integers ``a`` into a list of integers, ``a1`` having ``g = gcd(a1)``, and a list ``a2`` whose elements are not divisible by ``g``. Returns ``g, a1, a2``. Examples ======== >>> from sympy.simplify.radsimp import _split_gcd >>> _split_gcd(55, 35, 22, 14, 77, 10) (5, [55, 35, 10], [22, 14, 77]) rrHN)r!rP)r�r�rdrer4rhs r+rara�sy�� �!��A� ��B� �B� �q�r�r�U���� ��A�Y�Y�� ��7�7� �I�I�a�L�L�L�L��A� �I�I�a�L�L�L�L� �b�"�9�r-)NNFTr/)Tr�r6)D� collectionsr� sympy.corerrrrr�sympy.core.addr r �sympy.core.assumptionsr �sympy.core.exprtoolsr r �sympy.core.functionrrr�sympy.core.mulrrr�sympy.core.numbersrrr�sympy.core.parametersr�sympy.core.sortingrr�sympy.core.symbolrrr�sympy.functionsrrr�$sympy.functions.elementary.complexesr � sympy.polysr!�sympy.simplify.sqrtdenestr"�sympy.utilities.iterablesr#r$r�r�r�r�r�r>r)r!r#r rRrVrX� expand_numer� expand_denom�expand_fractionr@rar'r-r+�<module>r�s���#�#�#�#�#�#�7�7�7�7�7�7�7�7�7�7�7�7�7�7�0�0�0�0�0�0�0�0�.�.�.�.�.�.�3�3�3�3�3�3�3�3�G�G�G�G�G�G�G�G�G�G�B�B�B�B�B�B�B�B�B�B�1�1�1�1�1�1�1�1�1�1�3�3�3�3�3�3�8�8�8�8�8�8�8�8�2�2�2�2�2�2�2�2�2�2�*�*�*�*�*�*�*�*�*�*�4�4�4�4�4�4�������0�0�0�0�0�0�4�4�4�4�4�4�4�4� @�@�@�@�F���>L�L�L�L�^.�.�.�b(,�E�E�E�E�E�Pz,�z,�z,�z,�z%�%�%�,XL�XL�XL�XL�v*�*�*�*�*�*�*�*�+�+�+�-�-�-� -�-�-� � �� �!��&�&�&�R����r-
Memory