Esempio n. 1
0
    def __call__(self, equations, variables=None):
        
        if variables is None:
            variables = {}
        
        # Get a representation of the ODE system in the form of
        # dX/dt = M*X + B
        varnames, matrix, constants = get_linear_system(equations)

        # Make sure that the matrix M is constant, i.e. it only contains
        # external variables or constant variables
        t = Symbol('t', real=True, positive=True)
        symbols = set.union(*(el.atoms() for el in matrix))
        non_constant = _non_constant_symbols(symbols, variables, t)
        if len(non_constant):
            raise ValueError(('The coefficient matrix for the equations '
                              'contains the symbols %s, which are not '
                              'constant.') % str(non_constant))

        # Check for time dependence
        dt_var = variables.get('dt', None)
        if dt_var is not None:
            # This will raise an error if we meet the symbol "t" anywhere
            # except as an argument of a locally constant function
            for entry in itertools.chain(matrix, constants):
                _check_for_locally_constant(entry, variables, dt_var.get_value(), t)
        symbols = [Symbol(variable, real=True) for variable in varnames]
        solution = sp.solve_linear_system(matrix.row_join(constants), *symbols)
        b = sp.ImmutableMatrix([solution[symbol] for symbol in symbols]).transpose()
        
        # Solve the system
        dt = Symbol('dt', real=True, positive=True)
        A = (matrix * dt).exp()                
        C = sp.ImmutableMatrix([A.dot(b)]) - b
        _S = sp.MatrixSymbol('_S', len(varnames), 1)
        updates = A * _S + C.transpose()
        try:
            # In sympy 0.7.3, we have to explicitly convert it to a single matrix
            # In sympy 0.7.2, it is already a matrix (which doesn't have an
            # is_explicit method)
            updates = updates.as_explicit()
        except AttributeError:
            pass
        
        # The solution contains _S[0, 0], _S[1, 0] etc. for the state variables,
        # replace them with the state variable names 
        abstract_code = []
        for idx, (variable, update) in enumerate(zip(varnames, updates)):
            rhs = update
            for row_idx, varname in enumerate(varnames):
                rhs = rhs.subs(_S[row_idx, 0], varname)

            # Do not overwrite the real state variables yet, the update step
            # of other state variables might still need the original values
            abstract_code.append('_' + variable + ' = ' + sympy_to_str(rhs))
        
        # Update the state variables
        for variable in varnames:
            abstract_code.append('{variable} = _{variable}'.format(variable=variable))
        return '\n'.join(abstract_code)
Esempio n. 2
0
def ensure_matrix(M):
    if isinstance(M, unitbridge.Quantity):
        m = M.magnitude
        if isinstance(m, sympy.ImmutableMatrix):
            u = M.replace_magnitude(1)
            return sympy.ImmutableMatrix([[i * u for i in m.row(row)]
                                          for row in range(m.rows)])
        else:
            return sympy.ImmutableMatrix([M])
    elif not isinstance(M, sympy.ImmutableMatrix):
        return sympy.ImmutableMatrix([M])
    else:
        return M
Esempio n. 3
0
 def __init__(self,
              R,
              conjugate=False,
              antisymmetry=False,
              U=None,
              _strict_eq=False):
     if isinstance(R, sympy.ImmutableMatrix):
         # If it is integer, recast to integer tinyarray
         R = _make_int(R)
     elif isinstance(R, ta.ndarray_int):
         pass
     elif isinstance(R, ta.ndarray_float):
         R = _make_int(R)
     elif isinstance(R, sympy.matrices.MatrixBase):
         R = sympy.ImmutableMatrix(R)
         R = _make_int(R)
     elif isinstance(R, np.ndarray):
         # If it is integer, recast to integer tinyarray
         R = ta.array(R)
         R = _make_int(R)
     else:
         raise ValueError(
             'Real space rotation must be provided as a sympy matrix or an array.'
         )
     self.R, self.conjugate, self.antisymmetry, self.U = R, conjugate, antisymmetry, U
     # Calculating sympy inverse is slow, remember it
     self._strict_eq = _strict_eq
Esempio n. 4
0
def generate_c_code(expr,syms,func_name,tmp_dir,out_dir,verbose=False,request_delete_tmp_dir=True):
    
    tmp_dir_exists_before_call = os.path.exists(tmp_dir)

    syms = list(syms)

    if isinstance(expr,sympy.Matrix) or isinstance(expr,sympy.MutableMatrix) or isinstance(expr,sympy.ImmutableMatrix):
        out_sym = sympy.MatrixSymbol('out_%s' % abs(hash(sympy.ImmutableMatrix(expr))), *expr.shape)
        syms    = syms + [out_sym]

    if verbose: print "flashlight.sympy: Generating Cython code for %s..." % func_name
    _autowrap_skip_compile(expr=expr,backend="cython",verbose=verbose,args=syms,tempdir=tmp_dir)
    if verbose: print "flashlight.sympy: Modifying autogenerated Cython files and building..."

    with open("%s/setup.py" % tmp_dir, "r") as f:
        setup_py_str = f.read()
        tmp_module_name        = re.findall("wrapper_module_[0-9]*", setup_py_str)
        tmp_autofunc_code_name = re.findall("wrapped_code_[0-9]*",   setup_py_str)
        assert len(tmp_module_name)        == 2
        assert len(tmp_autofunc_code_name) == 1
        assert tmp_module_name[0] == tmp_module_name[1]
        tmp_module_name        = tmp_module_name[0]
        tmp_autofunc_code_name = tmp_autofunc_code_name[0]
    with open("%s/%s.c" % (tmp_dir,tmp_autofunc_code_name), "r") as f:
        autofunc_c_str = f.read()
    with open("%s/%s.h" % (tmp_dir,tmp_autofunc_code_name), "r") as f:
        autofunc_h_str = f.read()

    with open("%s/%s_autofunc.c" % (tmp_dir,func_name), "w") as f:
        autofunc_c_str_mod = autofunc_c_str
        autofunc_c_str_mod = autofunc_c_str_mod.replace("autofunc(", "%s_autofunc(" % func_name)
        autofunc_c_str_mod = autofunc_c_str_mod.replace('#include "%s.h"' % tmp_autofunc_code_name, '#include "%s.h"' % (func_name+"_autofunc"))
        f.write(autofunc_c_str_mod)
    with open("%s/%s_autofunc.h" % (tmp_dir,func_name), "w") as f:
        autofunc_h_str_mod = autofunc_h_str
        autofunc_h_str_mod = autofunc_h_str.replace("autofunc(", "%s_autofunc(" % func_name)
        autofunc_h_str_mod = autofunc_h_str_mod.replace("AUTOWRAP__%s__H" % tmp_autofunc_code_name.upper(), "%s_H" % (func_name+"_autofunc").upper())
        f.write(autofunc_h_str_mod)

    if not os.path.exists(out_dir):
        os.makedirs(out_dir)

    cmd = "cp %s/%s_autofunc.c %s/%s_autofunc.c" % (tmp_dir,func_name,out_dir,func_name)
    if verbose: print cmd
    output = subprocess.check_output(cmd, shell=True)
    if verbose and len(output) > 0: print output

    cmd = "cp %s/%s_autofunc.h %s/%s_autofunc.h" % (tmp_dir,func_name,out_dir,func_name)
    if verbose: print cmd
    output = subprocess.check_output(cmd, shell=True)
    if verbose and len(output) > 0: print output

    if not tmp_dir_exists_before_call and request_delete_tmp_dir:
        cmd = "rm -rf %s" % tmp_dir
        if verbose: print cmd
        output = subprocess.check_output(cmd, shell=True)
    if verbose and len(output) > 0: print output

    if verbose: print
Esempio n. 5
0
 def hess(self):
     """ `~sympy.matrices.immutable.ImmutableDenseMatrix` : \
          Second derivatives of :py:attr:`expr` with respect to \
          :py:attr:`prob.vars`. """
     if self._hess is None:
         self._hess = sym.ImmutableMatrix(
             self.grad.jacobian(self.prob.var_scalars))
     return self._hess
Esempio n. 6
0
 def grad(self):
     """ `~sympy.matrices.immutable.ImmutableDenseMatrix` : \
          First derivatives of :py:attr:`expr` with respect to \
          :py:attr:`prob.vars`. """
     if self._grad is None:
         self._grad = sym.ImmutableMatrix(
             [self.expr.diff(s) for s in self.prob.var_scalars])
     return self._grad
Esempio n. 7
0
 def update_subs(self, subs):
     if isinstance(self.length, math.Symbol):
         self.length = self.length.subs(subs)
     if self.pts_2D is not None and len(self.pts_2D) == 2 and len(
             self.pts_2D[0]) == 2:
         self.pts_2D = tuple(
             sympy.ImmutableMatrix([
                 dim.subs(subs) if isinstance(dim, sympy.Basic) else dim
                 for dim in p
             ]) for p in self.pts_2D)
     if self.pts_3D is not None and len(self.pts_3D) == 2 and len(
             self.pts_3D[0]) == 3:
         self.pts_3D = tuple(
             sympy.ImmutableMatrix([
                 dim.subs(subs) if isinstance(dim, sympy.Basic) else dim
                 for dim in p
             ]) for p in self.pts_3D)
Esempio n. 8
0
    def __init__(self, alpha, delta):
        H = sp.ImmutableMatrix(
            [[1 / 2 * alpha * _t, 1 / 2 * delta],
             [1 / 2 * sp.conjugate(delta), -1 / 2 * alpha * _t]])

        if not sp.S(delta).has(_t):
            self._lz_value = self.lz_formula(alpha, delta)
        else:
            self._lz_value = None
        QuantumSystem.__init__(self, H)
Esempio n. 9
0
def _mul(R1, R2):
    # Cached multiplication of spatial parts.
    if is_sympy_matrix(R1) and is_sympy_matrix(R2):
        # If spatial parts are sympy matrices, use cached multiplication.
        R = R1 * R2
    elif not (is_sympy_matrix(R1) or is_sympy_matrix(R2)):
        # If arrays, use dot
        R = ta.dot(R1, R2)
    elif ((is_sympy_matrix(R1) or is_sympy_matrix(R2)) and
        (isinstance(R1, ta.ndarray_int) or isinstance(R2, ta.ndarray_int))):
        # Multiplying sympy and integer tinyarray is ok, should result in sympy
        R = sympy.ImmutableMatrix(R1) * sympy.ImmutableMatrix(R2)
    else:
        raise ValueError("Mixing of sympy and floating point in the spatial part R is not allowed. "
                         "To avoid this error, make sure that all PointGroupElements are initialized "
                         "with either floating point arrays or sympy matrices as rotations. "
                         "Integer arrays are allowed in both cases.")
    R = _make_int(R)
    return R
Esempio n. 10
0
 def UnaryFunc(self, node, **kw):
     arg = self(node.arg)
     op = self(node.op)
     if isinstance(arg, sp.MatrixBase) and isinstance(node.op, IsElemwise):
         if arg.shape[1] != 1:
             raise NotImplementedError(
                 "Elementwise operations are only supported for vectors (column matrices)"
             )
         return sp.ImmutableMatrix([op(arg[i]) for i in range(len(arg))])
     else:
         return op(arg)
Esempio n. 11
0
def test_reading_different_matrix_types():
    test = [
        (sympy.MutableMatrix([kx**2])                    , ['x']),
        (sympy.ImmutableMatrix([kx**2])                  , ['x']),
        (sympy.MutableDenseMatrix([kx**2])               , ['x']),
        (sympy.ImmutableDenseMatrix([kx**2])             , ['x']),
    ]
    for inp, out in test:
        ham, got = discretize_symbolic(inp)
        assert got == out,\
            "Should be: _split_factors({})=={}. Not {}".format(inp, out, got)
Esempio n. 12
0
def get_foreman():
    # Basis transformation
    v_n = lambda i, N: sympy.Matrix(  # noqa: E731
        [1 if i == n else 0 for n in range(N)])
    S, X, Y, Z = [v_n(i, 4) for i in range(4)]
    up, dw = [v_n(i, 2) for i in range(2)]

    X = sympy.I * X
    Y = sympy.I * Y
    Z = sympy.I * Z

    molenkamp_basis = [
        kr(up, S),
        kr(dw, S),
        +(1 / sympy.sqrt(2)) * kr(up, X + sympy.I * Y),
        +(1 / sympy.sqrt(6)) * (kr(dw, X + sympy.I * Y) - kr(up, 2 * Z)),
        -(1 / sympy.sqrt(6)) * (kr(up, X - sympy.I * Y) + kr(dw, 2 * Z)),
        -(1 / sympy.sqrt(2)) * kr(dw, X - sympy.I * Y),
        +(1 / sympy.sqrt(3)) * (kr(dw, X + sympy.I * Y) + kr(up, Z)),
        +(1 / sympy.sqrt(3)) * (kr(up, X - sympy.I * Y) - kr(dw, Z)),
    ]

    subs_notation = {
        Ec: Ev + E0,
        L: -(g1 + 4 * g2) * (hbar**2 / 2 / m0),
        M: -(g1 - 2 * g2) * (hbar**2 / 2 / m0),
        Np: -(3 * g3 + (3 * kappa + 1)) * (hbar**2 / 2 / m0),
        Nm: -(3 * g3 - (3 * kappa + 1)) * (hbar**2 / 2 / m0),
        Ac: (g0 * hbar**2 / 2 / m0),
    }

    Hs = spin_orbit()

    Hcc = sympy.Matrix([Ec + kx * Ac * kx + ky * Ac * ky + kz * Ac * kz])
    Hcv = +sympy.I * sympy.Matrix([[P * kx, P * ky, P * kz]])
    Hvc = -sympy.I * sympy.Matrix([kx * P, ky * P, kz * P])

    data = [[valence_term(i, j) for j in range(3)] for i in range(3)]
    Hvv = sympy.Matrix(data)

    H4 = sympy.BlockMatrix([[Hcc, Hcv], [Hvc, Hvv]])
    H8 = sympy.Matrix(sympy.BlockDiagMatrix(H4, H4)) + Hs

    dag = lambda x: x.conjugate().transpose()  # noqa: E731
    U_dag = sympy.Matrix(sympy.BlockMatrix([molenkamp_basis]))
    U = dag(U_dag)

    hamiltonian = U * H8 * dag(U)
    hamiltonian = hamiltonian.subs(subs_notation)
    hamiltonian = hamiltonian + (Ev - Delta / 3) * sympy.diag(
        0, 0, 1, 1, 1, 1, 1, 1)
    return sympy.ImmutableMatrix(hamiltonian.expand())
Esempio n. 13
0
def gen_sigmas():
    """generate Pauli matrices.
    
    Usage:\n
    sp.Matrix(np.dot(vec, sigmas).reshape(2,2))
    """
    sigmas = []
    for i in range(4):
        if (i == 0):
            sigma = sp.Identity(2).as_explicit()
        else:
            sigma = sp.ImmutableMatrix(msigma(i))
        sigmas.append(sigma)
    return sigmas
Esempio n. 14
0
 def BinOp(self, node, **kw):
     left = self(node.left)
     right = self(node.right)
     op = self(node.op)
     if isinstance(left, sp.MatrixBase) and isinstance(
             right, sp.MatrixBase) and isinstance(node.op, IsElemwise):
         if left.shape != right.shape:
             raise ValueError("Shapes of the arguments do not match")
         if left.shape[1] != 1:
             raise NotImplementedError(
                 "Elementwise operations are only supported for vectors (column matrices)"
             )
         return sp.ImmutableMatrix(
             [op(left[i], right[i]) for i in range(len(left))])
     else:
         return op(left, right)
Esempio n. 15
0
    def _process_bound(self, b):
        if self.is_scalar:
            if not util.is_scalar(b):
                raise TypeError(
                    f"Variable {self.symbol} is a scalar but non-scalar bounds"
                    f"were provided.")
        else:
            shape = self.symbol.shape
            try:
                b = sym.ImmutableMatrix(b).reshape(*shape)
            except (TypeError, ValueError):
                b = b * sym.ones(*shape)

        b = sympify(b)
        if not self.prob.depends_only_on_params(b):
            raise ValueError(
                "Bounds can depend only on the symbols in prob.params")
        return b
Esempio n. 16
0
 def IfThenElse(self, node):
     # Piecewise function with matrix output is not a Matrix itself, which breaks some of the logic
     # Hence this won't work in general:
     test, iftrue, iffalse = self(node.test), self(node.iftrue), self(
         node.iffalse)
     if hasattr(iftrue, 'shape'):
         if iftrue.shape != iffalse.shape:
             raise ValueError("Shapes of the IF branches must match")
         if iftrue.shape[1] != 1:
             raise NotImplementedError(
                 "Elementwise operations are only supported for vectors (column matrices)"
             )
         return sp.ImmutableMatrix([
             sp.Piecewise((ift, test), (iff, True))
             for ift, iff in zip(iftrue, iffalse)
         ])
     else:
         return sp.Piecewise((iftrue, test), (iffalse, True))
Esempio n. 17
0
def test_spatial_types():
    S1 = PointGroupElement(sympy.eye(2), False, False, np.eye(3))
    S2 = PointGroupElement(sympy.Matrix([[0, 1], [1, 0]]), True, False,
                           np.eye(3))
    S3 = PointGroupElement(np.eye(2), False, False, 1j * np.eye(3))
    C6s = PointGroupElement(
        sympy.ImmutableMatrix([[sympy.Rational(1, 2),
                                sympy.sqrt(3) / 2],
                               [-sympy.sqrt(3) / 2,
                                sympy.Rational(1, 2)]]))
    C6f = PointGroupElement(
        np.array([[1 / 2, np.sqrt(3) / 2], [-np.sqrt(3) / 2, 1 / 2]]))

    assert S2**2 == S1
    assert not S1 == S2
    assert S1 == S3
    assert C6s == C6f
    # Mixing sympy with other types raises an error
    with raises(ValueError):
        S = C6s * C6f
Esempio n. 18
0
    def __init__(self,
                 symbolic_expression: sym.Expr,
                 argument_symbols: tp.Tuple[sym.Symbol, ...],
                 time_symbol: tp.Optional[sym.Symbol] = None,
                 symbolic_time_function_name_to_numeric_time_function_map: tp.
                 Optional[tp.Dict[str, tp.Callable]] = None,
                 perform_cse: bool = True,
                 lazy_initialization: bool = False,
                 pre_attach: bool = True,
                 dtype: np.generic = np.float32):

        super().__init__(
            argument_symbols=argument_symbols,
            time_symbol=time_symbol,
            symbolic_vector_expression=sym.ImmutableMatrix(
                [symbolic_expression]),
            symbolic_time_function_name_to_numeric_time_function_map=
            symbolic_time_function_name_to_numeric_time_function_map,
            perform_cse=perform_cse,
            lazy_initialization=lazy_initialization,
            pre_attach=pre_attach,
            dtype=dtype)
Esempio n. 19
0
    def __init__(self,
                 R,
                 conjugate=False,
                 antisymmetry=False,
                 U=None,
                 _strict_eq=False,
                 *,
                 locals=None):
        if isinstance(R, sympy.ImmutableMatrix):
            # If it is integer, recast to integer tinyarray
            R = _make_int(R)
        elif isinstance(R, ta.ndarray_int):
            pass
        elif isinstance(R, ta.ndarray_float):
            R = _make_int(R)
        elif isinstance(R, MatrixBase):
            R = sympy.ImmutableMatrix(R)
            R = _make_int(R)
        elif isinstance(R, np.ndarray):
            # If it is integer, recast to integer tinyarray
            R = ta.array(R)
            R = _make_int(R)
        else:
            raise ValueError(
                'Real space rotation must be provided as a sympy matrix or an array.'
            )
        # Normalize U
        if U is None:
            pass
        else:
            try:
                U = np.atleast_2d(np.array(U, dtype=complex))
            except (ValueError, TypeError):
                U = sympify(U, locals=locals)
                U = np.atleast_2d(np.array(U, dtype=complex))

        self.R, self.conjugate, self.antisymmetry, self.U = R, conjugate, antisymmetry, U
        # Calculating sympy inverse is slow, remember it
        self._strict_eq = _strict_eq
Esempio n. 20
0
    def _build_hamiltonian(self):
        # return foreman(self._parameter_coords, self.components, self.bands)
        if self._parameter_coords is not None:
            self._parameter_coords = validate_coords(self._parameter_coords)
            str_coords = "({})".format(", ".join(self._parameter_coords))
            subs = {v: v + str_coords for v in self._varied_parameters}
        else:
            subs = {}

        hamiltonian_components = [
            kwant.continuum.sympify(_models_cache[c], locals=subs)
            for c in self.components
        ]

        hamiltonian = sympy.ImmutableMatrix(
            sympy.MatAdd(*hamiltonian_components))

        indices = []
        for band in self.bands:
            indices += self._band_indices[band]

        return hamiltonian[:, indices][indices, :]
Esempio n. 21
0
import sympy as sp


class Permutation(tuple):
    def __mul__(self, s):
        return Permutation(self[x] for x in s)


def sg(elts):
    a = {}
    b = set(elts)
    while a != b:
        a = set(b)
        b |= {s1 * s2 for s1 in b for s2 in b}
    return b


print(sg({Permutation(x) for x in ((1, 2, 3, 0), (3, 2, 1, 0))}))

print(
    sg({sp.ImmutableMatrix(x)
        for x in (((1, 0), (0, -1)), ((0, -1), (1, 0)))}))
Esempio n. 22
0
    def __init__(self, alpha, delta):
        H = sp.ImmutableMatrix([[alpha * _t, delta, 0],
                                [delta.conjugate(), 0, delta],
                                [0, delta.conjugate(), -alpha * _t]])

        QuantumSystem.__init__(self, H)
Esempio n. 23
0
def test_bloch():
    # Simple tests for Bloch models

    # Hexagonal point group
    eyesym = sympy.ImmutableMatrix(sympy.eye(2))
    Mx = PointGroupElement(sympy.ImmutableMatrix([[-1, 0], [0, 1]]), False,
                           False, None)
    C6 = PointGroupElement(
        sympy.ImmutableMatrix([[sympy.Rational(1, 2),
                                sympy.sqrt(3) / 2],
                               [-sympy.sqrt(3) / 2,
                                sympy.Rational(1, 2)]]), False, False, None)
    TR = time_reversal(realspace_dim=2)
    PH = particle_hole(realspace_dim=2)
    gens_hex_2D = {Mx, C6, TR, PH}
    hex_group_2D = generate_group(gens_hex_2D)
    assert len(hex_group_2D) == 48

    # First example
    ham6 = 'm * (cos(k_x) + cos(1/2*k_x + sqrt(3)/2*k_y) + cos(-1/2*k_x + sqrt(3)/2*k_y))'
    H6 = Model(ham6, momenta=['k_x', 'k_y'])
    sg, Ps = discrete_symmetries(H6, hex_group_2D)
    assert [P.shape for P in Ps] == [(1, 1, 1)]
    assert len(sg) == 24
    assert sg == generate_group({Mx, C6, TR})

    # extend model to add SOC
    ham62 = 'eye(2) * (' + ham6 + ') +'
    ham62 += 'alpha * (sin(k_x) * sigma_x + sin(1/2*k_x + sqrt(3)/2*k_y) * (1/2*sigma_x + sqrt(3)/2*sigma_y) +'
    ham62 += 'sin(-1/2*k_x + sqrt(3)/2*k_y) * (-1/2*sigma_x + sqrt(3)/2*sigma_y))'
    H62 = Model(ham62, momenta=['k_x', 'k_y'])
    sg, Ps = discrete_symmetries(H62, hex_group_2D)
    assert [P.shape for P in Ps] == [(1, 2, 2)]
    assert len(sg) == 24
    assert sg == generate_group({Mx, C6, TR})

    # Add degeneracy
    ham63 = 'kron(eye(2), ' + ham62 + ')'
    H63 = Model(ham63, momenta=['k_x', 'k_y'])
    sg, Ps = discrete_symmetries(H63, hex_group_2D)
    assert [P.shape for P in Ps] == [(2, 4, 2)]
    assert len(sg) == 24
    assert sg == generate_group({Mx, C6, TR})

    # Add PH states
    ham64 = 'kron(sigma_z, ' + ham62 + ')'
    H64 = Model(ham64, momenta=['k_x', 'k_y'])
    sg, Ps = discrete_symmetries(H64, hex_group_2D)
    assert [P.shape for P in Ps] == [(1, 4, 2), (1, 4, 2)]
    assert len(sg) == 48
    assert sg == generate_group({Mx, C6, TR, PH})

    # Test sparse
    H64 = Model(ham64, momenta=['k_x', 'k_y'])
    sg, Ps = discrete_symmetries(H64, hex_group_2D, sparse_linalg=True)
    assert [P.shape for P in Ps] == [(1, 4, 2), (1, 4, 2)]
    assert len(sg) == 48
    assert sg == generate_group({Mx, C6, TR, PH})
    Hcsr = H64.tocsr()
    sg, Ps = discrete_symmetries(Hcsr, hex_group_2D, sparse_linalg=True)
    assert [P.shape for P in Ps] == [(1, 4, 2), (1, 4, 2)]
    assert len(sg) == 48
    assert sg == generate_group({Mx, C6, TR, PH})
    sg, Ps = discrete_symmetries(Hcsr, hex_group_2D, sparse_linalg=False)
    assert [P.shape for P in Ps] == [(1, 4, 2), (1, 4, 2)]
    assert len(sg) == 48
    assert sg == generate_group({Mx, C6, TR, PH})
Esempio n. 24
0
    def __init__(self, alpha, delta, epsilon):
        H = sp.ImmutableMatrix([[alpha * _t + epsilon, delta, 0],
                                [delta.conjugate(), 0, delta],
                                [0, delta.conjugate(), alpha * _t - epsilon]])

        QuantumSystem.__init__(self, H)
Esempio n. 25
0
    def __call__(self, equations, variables=None, method_options=None):
        method_options = extract_method_options(method_options,
                                                {'simplify': True})

        if equations.is_stochastic:
            raise UnsupportedEquationsException("Cannot solve stochastic "
                                                "equations with this state "
                                                "updater.")
        if variables is None:
            variables = {}

        # Get a representation of the ODE system in the form of
        # dX/dt = M*X + B
        varnames, matrix, constants = get_linear_system(equations, variables)

        # No differential equations, nothing to do (this occurs sometimes in the
        # test suite where the whole model is nothing more than something like
        # 'v : 1')
        if matrix.shape == (0, 0):
            return ''

        # Make sure that the matrix M is constant, i.e. it only contains
        # external variables or constant variables

        # Check for time dependence
        dt_value = variables['dt'].get_value(
        )[0] if 'dt' in variables else None

        # This will raise an error if we meet the symbol "t" anywhere
        # except as an argument of a locally constant function
        for entry in itertools.chain(matrix, constants):
            if not is_constant_over_dt(entry, variables, dt_value):
                raise UnsupportedEquationsException(
                    f"Expression '{sympy_to_str(entry)}' is not guaranteed to be "
                    f"constant over a time step.")

        symbols = [Symbol(variable, real=True) for variable in varnames]
        solution = sp.solve_linear_system(matrix.row_join(constants), *symbols)
        if solution is None or set(symbols) != set(solution.keys()):
            raise UnsupportedEquationsException("Cannot solve the given "
                                                "equations with this "
                                                "stateupdater.")
        b = sp.ImmutableMatrix([solution[symbol] for symbol in symbols])

        # Solve the system
        dt = Symbol('dt', real=True, positive=True)
        try:
            A = (matrix * dt).exp()
        except NotImplementedError:
            raise UnsupportedEquationsException("Cannot solve the given "
                                                "equations with this "
                                                "stateupdater.")
        if method_options['simplify']:
            A = A.applyfunc(
                lambda x: sp.factor_terms(sp.cancel(sp.signsimp(x))))
        C = sp.ImmutableMatrix(A * b) - b
        _S = sp.MatrixSymbol('_S', len(varnames), 1)
        updates = A * _S + C
        updates = updates.as_explicit()

        # The solution contains _S[0, 0], _S[1, 0] etc. for the state variables,
        # replace them with the state variable names
        abstract_code = []
        for idx, (variable, update) in enumerate(zip(varnames, updates)):
            rhs = update
            if rhs.has(I, re, im):
                raise UnsupportedEquationsException(
                    "The solution to the linear system "
                    "contains complex values "
                    "which is currently not implemented.")
            for row_idx, varname in enumerate(varnames):
                rhs = rhs.subs(_S[row_idx, 0], varname)

            # Do not overwrite the real state variables yet, the update step
            # of other state variables might still need the original values
            abstract_code.append(f"_{variable} = {sympy_to_str(rhs)}")

        # Update the state variables
        for variable in varnames:
            abstract_code.append(f"{variable} = _{variable}")
        return '\n'.join(abstract_code)
Esempio n. 26
0
def build_module_autowrap(expr,
                          syms,
                          module_name,
                          tmp_dir,
                          out_dir,
                          dummify=False,
                          cse=False,
                          cse_ordering="canonical",
                          build_vectorized=False,
                          pretty_dummy_symbol_names=False,
                          verbose=False,
                          request_delete_tmp_dir=True):

    tmp_dir_exists_before_call = os.path.exists(tmp_dir)

    is_matrix_expr = isinstance(expr, sympy.Matrix) or isinstance(
        expr, sympy.MutableMatrix) or isinstance(expr, sympy.ImmutableMatrix)

    if dummify:
        if verbose:
            print "flashlight.sympy: Generating dummy symbols for %s..." % module_name
        expr, syms = _dummify(expr, syms, pretty_dummy_symbol_names)
        if verbose:
            print "flashlight.sympy: Finished generating dummy symbols for %s." % module_name

    if cse:
        include_str, subexpr_eval_str = generate_c_code_cse(
            expr,
            syms,
            module_name,
            tmp_dir,
            out_dir,
            cse_ordering=cse_ordering,
            verbose=verbose,
            request_delete_tmp_dir=request_delete_tmp_dir)

        if is_matrix_expr:
            expr = sympy.Matrix.zeros(expr.rows, expr.cols)
        else:
            expr = 0

    syms = list(syms)

    if is_matrix_expr:
        out_sym = sympy.MatrixSymbol(
            'out_%s' % abs(hash(sympy.ImmutableMatrix(expr))), *expr.shape)
        syms = syms + [out_sym]

    if verbose:
        print "flashlight.sympy: Generating Cython code for %s..." % module_name
    _autowrap_skip_compile(expr=expr,
                           backend="cython",
                           verbose=verbose,
                           args=syms,
                           tempdir=tmp_dir)
    if verbose:
        print "flashlight.sympy: Modifying autogenerated Cython files for %s" % module_name

    with open("%s/setup.py" % tmp_dir, "r") as f:
        setup_py_str = f.read()
        tmp_module_name = re.findall("wrapper_module_[0-9]*", setup_py_str)
        tmp_autofunc_code_name = re.findall("wrapped_code_[0-9]*",
                                            setup_py_str)
        assert len(tmp_module_name) == 2
        assert len(tmp_autofunc_code_name) == 1
        assert tmp_module_name[0] == tmp_module_name[1]
        tmp_module_name = tmp_module_name[0]
        tmp_autofunc_code_name = tmp_autofunc_code_name[0]
    with open("%s/%s.pyx" % (tmp_dir, tmp_module_name), "r") as f:
        wrapper_module_pyx_str = f.read()
    with open("%s/%s.c" % (tmp_dir, tmp_autofunc_code_name), "r") as f:
        autofunc_c_str = f.read()
    with open("%s/%s.h" % (tmp_dir, tmp_autofunc_code_name), "r") as f:
        autofunc_h_str = f.read()

    with open("%s/%s_setup.py" % (tmp_dir, module_name), "w") as f:
        setup_py_str_mod = setup_py_str
        setup_py_str_mod = setup_py_str_mod.replace(
            "from Cython.Distutils import build_ext",
            "from Cython.Distutils import build_ext\n\nimport numpy\nimport os\n\nos.environ['CC']  = '%s'\nos.environ['CXX'] = '%s'\n\n"
            % (cc_compiler, cxx_compiler))
        setup_py_str_mod = setup_py_str_mod.replace(
            "extra_compile_args=['-std=c99']",
            "extra_compile_args=['-std=c99','-fno-var-tracking','-fno-var-tracking-assignments'], include_dirs=[numpy.get_include()]"
        )
        setup_py_str_mod = setup_py_str_mod.replace("%s" % tmp_module_name,
                                                    "%s" % module_name)
        setup_py_str_mod = setup_py_str_mod.replace(
            "%s" % tmp_autofunc_code_name, "%s_autofunc" % module_name)
        f.write(setup_py_str_mod)
    with open("%s/%s.pyx" % (tmp_dir, module_name), "w") as f:
        wrapper_module_pyx_str_mod = wrapper_module_pyx_str
        wrapper_module_pyx_str_mod = wrapper_module_pyx_str_mod.replace(
            "%s" % tmp_autofunc_code_name, "%s_autofunc" % module_name)
        f.write(wrapper_module_pyx_str_mod)

    if not cse:
        with open("%s/%s_autofunc.c" % (tmp_dir, module_name), "w") as f:
            autofunc_c_str_mod = autofunc_c_str
            autofunc_c_str_mod = autofunc_c_str_mod.replace(
                '#include "%s.h"' % tmp_autofunc_code_name,
                '#include "%s.h"' % (module_name + "_autofunc"))
            f.write(autofunc_c_str_mod)
        with open("%s/%s_autofunc.h" % (tmp_dir, module_name), "w") as f:
            autofunc_h_str_mod = autofunc_h_str
            autofunc_h_str_mod = autofunc_h_str_mod.replace(
                "AUTOWRAP__%s__H" % tmp_autofunc_code_name.upper(),
                "%s_H" % (module_name + "_autofunc").upper())
            f.write(autofunc_h_str_mod)

    if build_vectorized:
        if verbose:
            print "flashlight.sympy: Generating Cython code for %s_vectorized..." % module_name
        if is_matrix_expr:
            c_return_type_str = "void"
            c_out_var_str = "out_123456789"
            c_func_signature_str = str([
                "double %s" % str(sym) for sym in syms[:-1]
            ])[1:-1].replace("'", "") + ", double *%s" % syms[-1]
            cython_out_type_str = "numpy.ndarray[FLOAT64_DTYPE_t, ndim=3]"
            cython_out_shape_str = "(args.shape[0],%s,%s)" % (expr.rows,
                                                              expr.cols)
            cython_out_v_type_str = "FLOAT64_DTYPE_t [:,:,:]"
            cython_args_str = str([
                "args[i,%d]" % i for i in range(len(syms[:-1]))
            ])[1:-1].replace("'", "") + ", &out_v[i,0,0]"
            cython_loop_body_str = "autofunc(%s)" % cython_args_str
        else:
            c_return_type_str = "double"
            c_func_signature_str = str([
                "double %s" % str(sym) for sym in syms
            ])[1:-1].replace("'", "")
            cython_out_type_str = "numpy.ndarray[FLOAT64_DTYPE_t, ndim=1]"
            cython_out_shape_str = "(args.shape[0])"
            cython_out_v_type_str = "FLOAT64_DTYPE_t [:]"
            cython_args_str = str(["args[i,%d]" % i for i in range(len(syms))
                                   ])[1:-1].replace("'", "")
            cython_loop_body_str = "out_v[i] = autofunc(%s)" % cython_args_str
        vectorized_setup_py_str_eval = vectorized_setup_py_str % (
            cc_compiler, cxx_compiler, module_name, module_name, module_name)
        vectorized_pyx_str_eval = vectorized_pyx_str % (
            module_name, c_return_type_str, c_func_signature_str,
            cython_out_type_str, cython_out_shape_str, cython_out_v_type_str,
            cython_loop_body_str)
        with open("%s/%s_vectorized_setup.py" % (tmp_dir, module_name),
                  "w") as f:
            vectorized_setup_py_str_mod = vectorized_setup_py_str_eval
            f.write(vectorized_setup_py_str_mod)
        with open("%s/%s_vectorized.pyx" % (tmp_dir, module_name), "w") as f:
            vectorized_pyx_str_mod = vectorized_pyx_str_eval
            f.write(vectorized_pyx_str_mod)

    cwd = os.getcwd()
    try:
        os.chdir(tmp_dir)

        if verbose:
            print "flashlight.sympy: Building Cython code for %s..." % module_name
        cmd = "python %s_setup.py build_ext --inplace" % module_name
        if verbose: print cmd
        output = subprocess.check_output(cmd, shell=True)
        if verbose and len(output) > 0: print output

        if build_vectorized:
            if verbose:
                print "flashlight.sympy: Building Cython code for %s_vectorized..." % module_name
            cmd = "python %s_vectorized_setup.py build_ext --inplace" % module_name
            if verbose: print cmd
            output = subprocess.check_output(cmd, shell=True)
            if verbose and len(output) > 0: print output

    finally:
        os.chdir(cwd)

    if not os.path.exists(out_dir):
        os.makedirs(out_dir)

    cmd = "cp %s/%s.so %s/%s.so" % (tmp_dir, module_name, out_dir, module_name)
    if verbose: print cmd
    output = subprocess.check_output(cmd, shell=True)
    if verbose and len(output) > 0: print output

    if build_vectorized:
        cmd = "cp %s/%s_vectorized.so %s/%s_vectorized.so" % (
            tmp_dir, module_name, out_dir, module_name)
        if verbose: print cmd
        output = subprocess.check_output(cmd, shell=True)
        if verbose and len(output) > 0: print output

    # cmd = "cp %s/%s_autofunc.c %s/%s_autofunc.c" % (tmp_dir,module_name,out_dir,module_name)
    # if verbose: print cmd
    # output = subprocess.check_output(cmd, shell=True)
    # if verbose and len(output) > 0: print output

    # cmd = "cp %s/%s_autofunc.h %s/%s_autofunc.h" % (tmp_dir,module_name,out_dir,module_name)
    # if verbose: print cmd
    # output = subprocess.check_output(cmd, shell=True)
    # if verbose and len(output) > 0: print output

    if not tmp_dir_exists_before_call and request_delete_tmp_dir:
        cmd = "rm -rf %s" % tmp_dir
        if verbose: print cmd
        output = subprocess.check_output(cmd, shell=True)
        if verbose and len(output) > 0: print output
Esempio n. 27
0
    def __init__(self, alpha, delta, epsilon):
        H = sp.ImmutableMatrix([[epsilon + alpha * _t, delta, 0],
                                [delta.conjugate(), -2 * epsilon, delta],
                                [0, delta.conjugate(), epsilon - alpha * _t]])

        QuantumSystem.__init__(self, H)
Esempio n. 28
0
    def __call__(self, equations, variables=None, simplify=True):
        if equations.is_stochastic:
            raise UnsupportedEquationsException('Cannot solve stochastic '
                                                'equations with this state '
                                                'updater.')
        if variables is None:
            variables = {}

        # Get a representation of the ODE system in the form of
        # dX/dt = M*X + B
        varnames, matrix, constants = get_linear_system(equations, variables)

        # No differential equations, nothing to do (this occurs sometimes in the
        # test suite where the whole model is nothing more than something like
        # 'v : 1')
        if matrix.shape == (0, 0):
            return ''

        # Make sure that the matrix M is constant, i.e. it only contains
        # external variables or constant variables
        t = Symbol('t', real=True, positive=True)

        # Check for time dependence
        if 'dt' in variables:
            dt_value = variables['dt'].get_value()[0]

            # This will raise an error if we meet the symbol "t" anywhere
            # except as an argument of a locally constant function
            t = Symbol('t', real=True, positive=True)
            for entry in itertools.chain(matrix, constants):
                _check_for_locally_constant(entry, variables, dt_value, t)

        symbols = [Symbol(variable, real=True) for variable in varnames]
        solution = sp.solve_linear_system(matrix.row_join(constants), *symbols)
        if solution is None or set(symbols) != set(solution.keys()):
            raise UnsupportedEquationsException('Cannot solve the given '
                                                'equations with this '
                                                'stateupdater.')
        b = sp.ImmutableMatrix([solution[symbol]
                                for symbol in symbols]).transpose()

        # Solve the system
        dt = Symbol('dt', real=True, positive=True)
        try:
            A = (matrix * dt).exp()
        except NotImplementedError:
            raise UnsupportedEquationsException('Cannot solve the given '
                                                'equations with this '
                                                'stateupdater.')
        if simplify:
            A = A.applyfunc(
                lambda x: sp.factor_terms(sp.cancel(sp.signsimp(x))))
        C = sp.ImmutableMatrix([A.dot(b)]) - b
        _S = sp.MatrixSymbol('_S', len(varnames), 1)
        updates = A * _S + C.transpose()
        updates = updates.as_explicit()

        # The solution contains _S[0, 0], _S[1, 0] etc. for the state variables,
        # replace them with the state variable names
        abstract_code = []
        for idx, (variable, update) in enumerate(zip(varnames, updates)):
            rhs = update
            for row_idx, varname in enumerate(varnames):
                rhs = rhs.subs(_S[row_idx, 0], varname)

            # Do not overwrite the real state variables yet, the update step
            # of other state variables might still need the original values
            abstract_code.append('_' + variable + ' = ' + sympy_to_str(rhs))

        # Update the state variables
        for variable in varnames:
            abstract_code.append(
                '{variable} = _{variable}'.format(variable=variable))
        return '\n'.join(abstract_code)
Esempio n. 29
0
def hexagonal(dim=2,
              tr=True,
              ph=True,
              generators=False,
              sympy_R=True,
              spin=None):
    """
    Generate hexagonal point group in standard basis in 2 or 3 dimensions.
    Mirror symmetries with the main coordinate axes as normals are included.
    In 3D the hexagonal axis is the z axis.

    Parameters:
    -----------
    dim : int (default 2)
        Real sapce dimensionality, 2 or 3.
    tr, ph : bool (default True)
        Whether to include time-reversal and particle-hole
        symmetry.
    generators : bool (default True)
        Only return the group generators if True.
    sympy_R: bool (default True)
        Whether the rotation matrices should be exact sympy
        representations.
    spin : float or sequence of arrays (optional)
        Spin representation to use for the unitary action of the
        operator. If not provided, the PointGroupElements have the unitary
        action set to None. If float is provided, it should be integer or half-integer
        specifying the spin representation in the standard basis, see `spin_matrices`.
        Otherwise a sequence of 3 arrays of identical square size must be provided
        representing 3 components of the angular momentum operator. The unitary action
        of rotation operator is `U = exp(-i n⋅s)`. In 2D the z axis is assumed to be
        the rotation axis. If `ph` is True, `spin` may not be provided, as it is not
        possible to deduce the unitary representation of particle-hole symmetry from
        spin alone. In this case construct the particle-hole operator manually.

    Returns:
    --------
    set of PointGroupElements

    Notes:
    ------
        Warning: in 2D the real space action of a mirror and and a 2-fold rotation
        around an axis in the plane is identical, however the action on angular momentum
        is different. Here we consider the action of the mirror, which is the same as the
        action of a 2-fold rotation around the mirror axis, assuming inversion acts trivially.
    """
    if spin is not None and sympy_R:
        U6 = spin_rotation(np.pi / 3 * np.array([0, 0, 1]), spin)
    else:
        U6 = None
    if dim == 2:
        Mx = mirror([1, 0], spin=spin)
        if sympy_R:

            C6 = PointGroupElement(
                sympy.ImmutableMatrix(
                    [[sympy.Rational(1, 2),
                      sympy.sqrt(3) / 2],
                     [-sympy.sqrt(3) / 2,
                      sympy.Rational(1, 2)]]), False, False, U6)
        else:
            C6 = rotation(1 / 6, spin=spin)
        gens = {Mx, C6}
    elif dim == 3:
        I = inversion(
            3, U=(None if spin is None else spin_rotation(np.zeros(3), spin)))
        C2x = rotation(1 / 2, [1, 0, 0], spin=spin)
        if sympy_R:
            C6 = PointGroupElement(
                sympy.ImmutableMatrix(
                    [[sympy.Rational(1, 2),
                      sympy.sqrt(3) / 2, 0],
                     [-sympy.sqrt(3) / 2,
                      sympy.Rational(1, 2), 0], [0, 0, 1]]), False, False, U6)
        else:
            C6 = rotation(1 / 6, [0, 0, 1], spin=spin)
        gens = {I, C2x, C6}
    else:
        raise ValueError('Only 2 and 3 dimensions are supported.')

    if tr:
        TR = time_reversal(dim, spin=spin)
        gens.add(TR)
    if ph:
        PH = particle_hole(dim)
        gens.add(PH)
    if generators:
        return gens
    else:
        return generate_group(gens)
Esempio n. 30
0
    def __init__(self,
                 symbolic_array_expressions: tp.Tuple[tp.Union[sym.Array,
                                                               sym.MatrixBase],
                                                      ...],
                 argument_symbols: tp.Tuple[sym.Symbol],
                 time_symbol: tp.Optional[sym.Symbol] = None,
                 symbolic_time_function_name_to_numeric_time_function_map: tp.
                 Optional[tp.Dict[str, tp.Callable]] = None,
                 squeeze_column_vectors: tp.Optional[tp.Tuple[bool,
                                                              ...]] = None,
                 perform_cse: bool = True,
                 lazy_initialization: bool = False,
                 pre_attach: tp.Optional[tp.Tuple[bool, ...]] = None,
                 dtype: np.generic = np.float32):

        if time_symbol is None:
            if symbolic_time_function_name_to_numeric_time_function_map is not None and \
                    len(symbolic_time_function_name_to_numeric_time_function_map) != 0:
                raise ValueError(
                    'Argument time_symbol must not be none if '
                    'symbolic_time_function_name_to_numeric_time_function_map '
                    'is provided.')

            if any([
                    DUMMY_TIME_SYMBOL in symbolic_array_expression.free_symbols
                    for symbolic_array_expression in symbolic_array_expressions
            ]):
                raise ValueError('Argument time_symbol must be provided '
                                 'explicity if expression contains '
                                 'DUMMY_TIME_SYMBOL.')

            time_symbol = DUMMY_TIME_SYMBOL
            self._time_symbol_provided = False
        else:
            self._time_symbol_provided = True

        if symbolic_time_function_name_to_numeric_time_function_map is None:
            symbolic_time_function_name_to_numeric_time_function_map = dict()

        symbolic_array_expressions \
            = tuple(check_and_make_sequence(symbolic_array_expressions,
                                            sym.MatrixBase))

        # print(f'{symbolic_array_expressions=}\n')
        symbolic_array_expressions = \
                tuple(sym.ImmutableMatrix(symbolic_array_expression)
                      if isinstance(symbolic_array_expression, sym.MatrixBase)
                      else sym.ImmutableDenseNDimArray(symbolic_array_expression)
                      for symbolic_array_expression
                      in symbolic_array_expressions)

        if pre_attach is None:
            pre_attach = len(symbolic_array_expressions) * [True]
        pre_attach = check_and_make_sequence(pre_attach, bool)

        if squeeze_column_vectors is None:
            squeeze_column_vectors = len(symbolic_array_expressions) * [False]
        squeeze_column_vectors = check_and_make_sequence(
            squeeze_column_vectors, bool)

        if not (len(symbolic_array_expressions) == len(pre_attach)
                and len(symbolic_array_expressions)
                == len(squeeze_column_vectors)):
            raise ValueError(
                "symbolic_matrix_expressions, pre_attach, and "
                "squeeze_column_vectors must have the same number "
                "of elements")

        self._argument_symbols = argument_symbols
        self._time_symbol = time_symbol
        self._symbolic_array_expressions = symbolic_array_expressions
        self._symbolic_time_function_name_to_numeric_time_function_map = \
            symbolic_time_function_name_to_numeric_time_function_map
        self._squeeze_column_vectors = squeeze_column_vectors
        self._symbols = \
            tuple([time_symbol] +
                   list(argument_symbols))

        self._perform_cse = perform_cse
        self._pre_attach = pre_attach
        self._dtype = dtype

        self._shapes \
            = tuple([symbolic_array_expression.shape
                     for symbolic_array_expression
                     in symbolic_array_expressions])

        if lazy_initialization:
            self._functions_cpu = None
            self._functions_gpu = None
        else:
            self._perform_initialization()