def __init__(self, *args, **keyword_args): # If there is one argument, then the user only gave a control # function. Assume a qubit system, i.e. SU(2^n). if len(args) == 1: self.ideal_control = args[0] dim = self.ideal_control.number_controls # Convert Lie dimensonality into number of qubits. n = log( dim + 1 ) / log( 4 ) self.number_qubits = n self.lie_algebra = "su(%i)" %(int(2**n)) if n == 1: self.hamiltonians = [Hx,Hy,Hz] else: self.hamiltonians = routines.product_operator( n ) # If there are two arguments, then the user gave both a set of # controls and also a set of Hamiltonians. elif len(args) == 2: self.ideal_control = args[0] self.hamiltonians = args[1] # If there are three arguments, then the user gave controls, # Hamiltonians and Lindblad operators. elif len(args) == 3: self.ideal_control = args[0] self.hamiltonians = args[1] self.lindblad = args[2] # Since Lindblad operators were specified, we should use # Master equation methods. Calculate superoperator # representations of relevant operators. if not len( self.ideal_control ) == len( self.hamiltonians ): raise ValueError("Control dimension mismatch. Controls and " + \ "Hamiltonians must be of the same length.") # Carry over several constants from controls self.dimension = self.ideal_control.dimension self.times = self.ideal_control.times self.timemin = self.ideal_control.timemin self.timemax = self.ideal_control.timemax # Create an control. For propagator instances, these are # identical to ideal_control, however for imperfect instances # these differ. self.control = self.ideal_control.copy() # Parse through keyword arguments. Sets default solution # method. Other keywords that are not understood will be # quietly ignored. if keyword_args.has_key( 'solution' ): method = keyword_args['solution'] valid_inputs = ['trotter', 'dyson', 'magnus', 'lindblad'] if method in valid_inputs: self.solution_method = method else: # Keyword was not valid. Check to see if already # defined. # Return to default and warn user self.solution_method = 'trotter' warn('Solution method not understood, defaulting to \'trotter\'.') else: # set default solution method self.solution_method = 'trotter' # Set order of pertubation theory default_order = 4 if keyword_args.has_key( 'order' ): order = keyword_args['order'] try: if (order % 1.0) == 0: self.order = order else: # Order was not an integer, revert to defaults warn('Pertubation theory order must be integer valued.') self.order = default_order except TypeError: # Order was not numeric, revert to defaults warn('Pertubation theory order must be integer valued.') self.order = default_order else: # Set default order self.order = default_order
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from quantop import * import control import integration import routines import imperfect __all__ = ['propagator','rotation','R'] [Hx,Hy,Hz] = routines.product_operator(1) class propagator: """ A class for quantum dynamical propagators. The evolution is specified by a bilinear control system, and optionally, a set of Linblad decay channels. Inputs may be an instance of the control class and also lists of N x N matrices, where N is the dimensionality of the Hilbert space. If no Lindblad channels are specified, then the evolution is assumed to be unitary. If no Hamiltonians are specified and the dimensionality of the control system is n(n-1), then we assume the dynamical Lie algebra is SU(2^n) and use a product-operator basis for the