U
    ZÊ¹j[%  ã                   @   sü   d Z ddlmZmZmZmZmZmZmZ ddl	m
Z
 ddlmZmZmZ ddlmZmZmZmZmZmZmZ ddgZeeeefƒeeeefƒeeeefƒee
eeeeefƒeeeeiZdd	„ e ¡ D ƒZd
d„ Zdd„ Zdd„ Zdd„ Zdd„ Z dd„ Z!dS )a   A module for mapping operators to their corresponding eigenstates
and vice versa

It contains a global dictionary with eigenstate-operator pairings.
If a new state-operator pair is created, this dictionary should be
updated as well.

It also contains functions operators_to_state and state_to_operators
for mapping between the two. These can handle both classes and
instances of operators and states. See the individual function
descriptions for details.

TODO List:
- Update the dictionary with a complete list of state-operator pairs
é    )ÚXOpÚYOpÚZOpÚXKetÚPxOpÚPxKetÚPositionKet3D)ÚOperator)Ú	StateBaseÚBraBaseÚKet)ÚJxOpÚJyOpÚJzOpÚJ2OpÚJxKetÚJyKetÚJzKetÚoperators_to_stateÚstate_to_operatorsc                 C   s   i | ]\}}||“qS © r   )Ú.0ÚkÚvr   r   ú`/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/physics/quantum/operatorset.pyÚ
<dictcomp>,   s      r   c           	      K   s\  t | ttfƒs t| tƒs tdƒ‚t | tƒræ| D ] }t |tƒs.t|tƒs.tdƒ‚q.t| ƒ}|tkrªz(dd„ |D ƒ}tt| t|ƒf|Ž}W n tk
r¤   t| }Y nX |S dd„ |D ƒ}t|ƒ}|tkrÜtt| |f|Ž}nd}|S nr| tk�r0z| ƒ }tt|  |f|Ž}W n tk
�r*   t|  }Y nX |S t| ƒtk�rTttt| ƒ | f|ŽS dS dS )a.   Returns the eigenstate of the given operator or set of operators

    A global function for mapping operator classes to their associated
    states. It takes either an Operator or a set of operators and
    returns the state associated with these.

    This function can handle both instances of a given operator or
    just the class itself (i.e. both XOp() and XOp)

    There are multiple use cases to consider:

    1) A class or set of classes is passed: First, we try to
    instantiate default instances for these operators. If this fails,
    then the class is simply returned. If we succeed in instantiating
    default instances, then we try to call state._operators_to_state
    on the operator instances. If this fails, the class is returned.
    Otherwise, the instance returned by _operators_to_state is returned.

    2) An instance or set of instances is passed: In this case,
    state._operators_to_state is called on the instances passed. If
    this fails, a state class is returned. If the method returns an
    instance, that instance is returned.

    In both cases, if the operator class or set does not exist in the
    state_mapping dictionary, None is returned.

    Parameters
    ==========

    arg: Operator or set
         The class or instance of the operator or set of operators
         to be mapped to a state

    Examples
    ========

    >>> from sympy.physics.quantum.cartesian import XOp, PxOp
    >>> from sympy.physics.quantum.operatorset import operators_to_state
    >>> from sympy.physics.quantum.operator import Operator
    >>> operators_to_state(XOp)
    |x>
    >>> operators_to_state(XOp())
    |x>
    >>> operators_to_state(PxOp)
    |px>
    >>> operators_to_state(PxOp())
    |px>
    >>> operators_to_state(Operator)
    |psi>
    >>> operators_to_state(Operator())
    |psi>
    z%Argument is not an Operator or a set!zSet is not all Operators!c                 S   s   g | ]
}|ƒ ‘qS r   r   )r   Úopr   r   r   Ú
<listcomp>t   s     z&operators_to_state.<locals>.<listcomp>c                 S   s   g | ]}t |ƒ‘qS r   )Útype)r   Úor   r   r   r   {   s     N)	Ú
isinstancer	   ÚsetÚ
issubclassÚNotImplementedErrorÚ	frozensetÚ
op_mappingÚ
_get_stater   )	Ú	operatorsÚoptionsÚsÚopsZop_instancesÚretÚtmpÚclassesZop_instancer   r   r   r   /   s@    6

ÿ

c              	   K   s2  t | tƒst| tƒstdƒ‚| tkrjt| ƒ}zt|tt|  ƒf|Ž}W n  ttfk
rf   t|  }Y nX nÀt	| ƒtkr’t| ttt	| ƒ ƒf|Ž}n˜t | t
ƒrÀ|  ¡ tkrÀt| tt|  ¡  ƒƒ}njt| t
ƒ�r&|  ¡ tk�r&t| ƒ}zt|tt|  ¡  ƒƒ}W n& ttfk
�r"   t|  ¡  }Y nX nd}t|ƒS )a`   Returns the operator or set of operators corresponding to the
    given eigenstate

    A global function for mapping state classes to their associated
    operators or sets of operators. It takes either a state class
    or instance.

    This function can handle both instances of a given state or just
    the class itself (i.e. both XKet() and XKet)

    There are multiple use cases to consider:

    1) A state class is passed: In this case, we first try
    instantiating a default instance of the class. If this succeeds,
    then we try to call state._state_to_operators on that instance.
    If the creation of the default instance or if the calling of
    _state_to_operators fails, then either an operator class or set of
    operator classes is returned. Otherwise, the appropriate
    operator instances are returned.

    2) A state instance is returned: Here, state._state_to_operators
    is called for the instance. If this fails, then a class or set of
    operator classes is returned. Otherwise, the instances are returned.

    In either case, if the state's class does not exist in
    state_mapping, None is returned.

    Parameters
    ==========

    arg: StateBase class or instance (or subclasses)
         The class or instance of the state to be mapped to an
         operator or set of operators

    Examples
    ========

    >>> from sympy.physics.quantum.cartesian import XKet, PxKet, XBra, PxBra
    >>> from sympy.physics.quantum.operatorset import state_to_operators
    >>> from sympy.physics.quantum.state import Ket, Bra
    >>> state_to_operators(XKet)
    X
    >>> state_to_operators(XKet())
    X
    >>> state_to_operators(PxKet)
    Px
    >>> state_to_operators(PxKet())
    Px
    >>> state_to_operators(PxBra)
    Px
    >>> state_to_operators(XBra)
    X
    >>> state_to_operators(Ket)
    O
    >>> state_to_operators(Bra)
    O
    zArgument is not a state!N)r    r
   r"   r#   Ústate_mappingÚ_make_defaultÚ_get_opsÚ	_make_setÚ	TypeErrorr   r   Z
dual_class)Ústater(   Ú
state_instr+   r   r   r   r   “   s@    ;
ÿÿÿÿÿÿc                 C   s(   z
| ƒ }W n t k
r"   | }Y nX |S ©N)r2   )Úexprr+   r   r   r   r/   ë   s
    

r/   c                 K   s4   z| j |f|Ž}W n tk
r.   t| ƒ}Y nX |S r5   )Z_operators_to_stater#   r/   )Zstate_classr*   r(   r+   r   r   r   r&   ÷   s
    r&   c                 K   sv   z| j |f|Ž}W n@ tk
rR   t|tttfƒrFtdd„ |D ƒƒ}nt|ƒ}Y nX t|tƒrrt|ƒdkrr|d S |S )Nc                 s   s   | ]}t |ƒV  qd S r5   )r/   )r   Úxr   r   r   Ú	<genexpr>	  s     z_get_ops.<locals>.<genexpr>é   r   )Z_state_to_operatorsr#   r    r!   Útupler$   r/   Úlen)r4   Z
op_classesr(   r+   r   r   r   r0     s    r0   c                 C   s    t | tttfƒrt| ƒS | S d S r5   )r    r:   Úlistr$   r!   )r*   r   r   r   r1     s    r1   N)"Ú__doc__Zsympy.physics.quantum.cartesianr   r   r   r   r   r   r   Zsympy.physics.quantum.operatorr	   Zsympy.physics.quantum.stater
   r   r   Zsympy.physics.quantum.spinr   r   r   r   r   r   r   Ú__all__r$   r.   Úitemsr%   r   r   r/   r&   r0   r1   r   r   r   r   Ú<module>   s8   $$þ 
 
    údX