Ejemplo n.º 1
0
 def grad(self, var):
     if var not in self.free_symbols:
         return Sum([], self.dom, self.cod)
     name = "{}.grad({})".format(self.name, var)
     n_bits_in, n_bits_out = len(self.dom), len(self.cod)
     array = self.eval().grad(var).array
     return ClassicalGate(name, n_bits_in, n_bits_out, array)
Ejemplo n.º 2
0
 def grad(self, var):
     if len(self.dom) != 1:
         raise NotImplementedError
     if var not in self.free_symbols:
         return Sum([], self.dom, self.cod)
     gradient = self.phase.diff(var)
     gradient = complex(gradient) if not gradient.free_symbols else gradient
     return scalar(.5j * gradient) @ type(self)(self.phase - .5)
Ejemplo n.º 3
0
 def grad(self, var, **params):
     if var not in self.free_symbols:
         return Sum([], self.dom, self.cod)
     if params.get('mixed', True):
         return super().grad(var, **params)
     gradient = self.phase.diff(var)
     gradient = complex(gradient) if not gradient.free_symbols else gradient
     _i_2_pi = 1j * 2 * self.modules.pi
     s = scalar(_i_2_pi * gradient * self.modules.exp(_i_2_pi * self.phase))
     return _outer_prod_diag(1, 1) @ s
Ejemplo n.º 4
0
 def grad(self, var, **params):
     if var not in self.free_symbols:
         return Sum([], self.dom, self.cod)
     if params.get('mixed', True):
         return super().grad(var, **params)
     gradient = self.phase.diff(var)
     gradient = complex(gradient) if not gradient.free_symbols else gradient
     _i_half_pi = .5j * self.modules.pi
     op1 = Z @ X @ scalar(_i_half_pi * gradient)
     op2 = Id(qubit) @ X @ scalar(-_i_half_pi * gradient)
     return self >> (op1 + op2)
Ejemplo n.º 5
0
    def grad(self, var, **params):
        if var not in self.free_symbols:
            return Sum([], self.dom, self.cod)
        gradient = self.phase.diff(var)
        gradient = complex(gradient) if not gradient.free_symbols else gradient

        if params.get('mixed', True):
            if len(self.dom) != 1:
                raise NotImplementedError
            s = scalar(Tensor.np.pi * gradient, is_mixed=True)
            t1 = type(self)(self.phase + .25)
            t2 = type(self)(self.phase - .25)
            return s @ (t1 + scalar(-1, is_mixed=True) @ t2)

        return scalar(Tensor.np.pi * gradient) @ type(self)(self.phase + .5)
Ejemplo n.º 6
0
 def grad(self, var, **params):
     if var not in self.free_symbols:
         return Sum([], self.dom, self.cod)
     return Scalar(self.array[0].diff(var))
Ejemplo n.º 7
0
 def grad(self, var, **params):
     if var not in self.free_symbols:
         return Sum([], self.dom, self.cod)
     name = "{}.grad({})".format(self.name, var)
     data = self.eval().grad(var, **params).array
     return ClassicalGate(name, self.dom, self.cod, data)