Example #1
0
 def _update(graph, leaves, root, n_branch, prefix='A'):
     subtree, r = huffman_tree(leaves, prefix=prefix)
     try:
         subtree[root] = subtree.pop(r)
         graph.update(subtree)
     except KeyError:
         pass
     return
Example #2
0
def tensor_tree_template(init_rho, pb_index, rank=1, nbranch=2):
    """Get rho_n from rho in a Tensor Tree representation.

    Parameters
    ----------
    rho : np.ndarray
    """
    n_state = get_n_state(init_rho)
    n_vec = np.zeros((rank, ), dtype=DTYPE)
    n_vec[0] = 1.0
    root_array = np.tensordot(init_rho, n_vec, axes=0)
    max_terms = len(pb_index)

    for i in pb_index:
        assert rank <= i

    # generate leaves
    leaves = list(range(max_terms))

    class new_spf(object):
        counter = 0
        prefix = 'SPF'

        def __new__(cls):
            name = cls.prefix + str(cls.counter)
            cls.counter += 1
            return name

    importance = list(reversed(range(len(pb_index))))
    graph, spf_root = huffman_tree(
        leaves,
        importances=importance,
        obj_new=new_spf,
        n_branch=nbranch,
    )

    root = 'root'
    graph[root] = [str(max_terms), str(max_terms + 1), spf_root]

    print(graph, root)

    root = Tensor.generate(graph, root)
    root.set_array(root_array)
    bond_dict = {}
    # Leaves
    l_range = list(pb_index) + [n_state] * 2
    for s, i, t, j in root.linkage_visitor():
        if isinstance(t, Leaf):
            bond_dict[(s, i, t, j)] = l_range[int(t.name)]
        else:
            bond_dict[(s, i, t, j)] = rank
    autocomplete(root, bond_dict)

    return root
Example #3
0
    def _update(graph, leaves, root, n_branch, prefix='A'):
        def obj_new(x=0):
            x += 1
            return str(prefix) + str(x)

        subtree, r = huffman_tree(leaves, obj_new=obj_new)
        try:
            subtree[root] = subtree.pop(r)
            graph.update(subtree)
        except KeyError:
            pass
        return
Example #4
0
def test_mctdh(fname=None):
    sys_leaf = Leaf(name='sys0')

    ph_leaves = []
    for n, (omega, g) in enumerate(ph_parameters, 1):
        ph_leaf = Leaf(name='ph{}'.format(n))
        ph_leaves.append(ph_leaf)

    def ph_spf():
        t = Tensor(axis=0)
        t.name = 'spf' + str(hex(id(t)))[-4:]
        return t

    graph, root = huffman_tree(ph_leaves, obj_new=ph_spf, n_branch=2)
    try:
        graph[root].insert(0, sys_leaf)
    except KeyError:
        ph_leaf = root
        root = Tensor()
        graph[root] = [sys_leaf, ph_leaf]
    finally:
        root.name = 'wfn'
        root.axis = None

    stack = [root]
    while stack:
        parent = stack.pop()
        for child in graph[parent]:
            parent.link_to(parent.order, child, 0)
            if child in graph:
                stack.append(child)

    # Define the detailed parameters for the ML-MCTDH tree
    h_list = model.wfn_h_list(sys_leaf, ph_leaves)
    solver = MultiLayer(root, h_list)
    bond_dict = {}
    # Leaves
    for s, i, t, j in root.linkage_visitor():
        if t.name.startswith('sys'):
            bond_dict[(s, i, t, j)] = 2
        else:
            if isinstance(t, Leaf):
                bond_dict[(s, i, t, j)] = max_tier
            else:
                bond_dict[(s, i, t, j)] = rank_wfn
    solver.autocomplete(bond_dict)
    # set initial root array
    init_proj = np.array([[A, 0.0], [B, 0.0]]) / np.sqrt(A**2 + B**2)
    root_array = Tensor.partial_product(root.array, 0, init_proj, 1)
    root.set_array(root_array)

    solver = MultiLayer(root, h_list)
    solver.ode_method = 'RK45'
    solver.cmf_steps = solver.max_ode_steps  # constant mean-field
    solver.ps_method = 'split'
    solver.svd_err = 1.0e-14

    # Define the obersevable of interest
    logger = Logger(filename=prefix + fname, level='info').logger
    logger2 = Logger(filename=prefix + 'en_' + fname, level='info').logger
    for n, (time, r) in enumerate(
            solver.propagator(
                steps=count,
                ode_inter=dt_unit,
                split=True,
            )):
        if n % callback_interval == 0:
            t = Quantity(time).convert_to(unit='fs').value
            rho = r.partial_env(0, proper=False)
            logger.info("{}    {} {} {} {}".format(t, rho[0, 0], rho[0, 1],
                                                   rho[1, 0], rho[1, 1]))
            en = np.trace(rho @ model.h)
            logger2.info('{}    {}'.format(t, en))
Example #5
0
def ml(fname,
       e,
       v,
       primitive_dim,
       spf_dim,
       ph_parameters,
       steps=2000,
       ode_inter=0.1):
    logger = Logger(filename=fname).logger

    # define parameters
    sys_hamiltonian = np.array([[e, v], [v, -e]], dtype=DTYPE)
    projector = np.array([[1.0, 0.0], [0.0, -1.0]],
                         dtype=DTYPE)  # S in H_SB = S x B

    primitive_dim = primitive_dim
    spf_dim = spf_dim

    # Define all Leaf tensors and hamiltonian we need
    h_list = []
    sys_leaf = Leaf(name='sys0')
    h_list.append([(sys_leaf, -1.0j * sys_hamiltonian)])

    ph_parameters = ph_parameters

    leaves = []
    for n, (omega, g) in enumerate(ph_parameters, 1):
        ph = Phonon(primitive_dim, omega)
        ph_leaf = Leaf(name='ph{}'.format(n))
        leaves.append(ph_leaf)
        # hamiltonian ph part
        h_list.append([(ph_leaf, -1.0j * ph.hamiltonian)])
        # e-ph part
        op = ph.annihilation_operator + ph.creation_operator
        h_list.append([(ph_leaf, g * op), (sys_leaf, -1.0j * projector)])

    def ph_spf():
        t = Tensor(axis=0, normalized=True)
        t.name = str(hex(id(t)))[-4:]
        return t

    graph, root = huffman_tree(leaves, obj_new=ph_spf, n_branch=2)
    try:
        graph[root].insert(0, sys_leaf)
    except KeyError:
        ph_leaf = root
        root = Tensor()
        graph[root] = [sys_leaf, ph_leaf]
    finally:
        root.name = 'wfn'
        root.axis = None
        root.normalized = True
    stack = [root]
    while stack:
        parent = stack.pop()
        for child in graph[parent]:
            parent.link_to(parent.order, child, 0)
            if child in graph:
                stack.append(child)
    logger.info(f"graph:{graph}")

    # Define the detailed parameters for the ML-MCTDH tree
    solver = MultiLayer(root, h_list)
    bond_dict = {}
    # Leaves
    for s, i, t, j in root.linkage_visitor():
        if t.name and t.name.startswith('sys'):
            bond_dict[(s, i, t, j)] = 2
        else:
            if isinstance(t, Leaf):
                bond_dict[(s, i, t, j)] = primitive_dim
            else:
                bond_dict[(s, i, t, j)] = spf_dim
    solver.autocomplete(bond_dict)
    logger.info(f"bond_dict:{bond_dict}")
    # set initial root array
    a, b = 1.0, 0
    init_proj = np.array([[a, 0.0], [b, 0.0]]) / np.sqrt(a**2 + b**2)
    root_array = Tensor.partial_product(root.array, 0, init_proj, 1)
    root.set_array(root_array)

    # Define the computation details
    solver.ode_method = 'RK45'
    solver.snd_order = False
    solver.cmf_steps = 100
    # Define the obersevable of interest
    logger.info('''# time    rho00  rho01  rho10  rho11''')
    for time, _ in solver.propagator(
            steps=steps,
            ode_inter=ode_inter,
            split=True,
    ):
        t = time
        for tensor in root.visitor(axis=None):
            tensor.reset()
            tensor.normalize(forced=True)
        rho = root.partial_env(0, proper=False)
        for tensor in root.visitor(axis=None):
            tensor.reset()
        flat_data = [t] + list(np.reshape(rho, -1))
        logger.info('{}    {}  {}  {}  {}'.format(*flat_data))
Example #6
0
def ml(dof, e, v, eta, cutoff, scale=5, loc=None, steps=2000, ode_inter=0.1):
    f_ = 'dof{}-eta{}.log'.format(dof, eta)
    logger = Logger(filename=f_).logger

    # define parameters
    e = Quantity(e, 'cm-1').value_in_au
    v = Quantity(v, 'cm-1').value_in_au
    eta = Quantity(eta, 'cm-1').value_in_au
    omega0 = Quantity(cutoff, 'cm-1').value_in_au
    sys_hamiltonian = np.array([[-e / 2.0, v], [v, e / 2.0]], dtype=DTYPE)
    projector = np.array([[0.0, 0.0], [0.0, 1.0]],
                         dtype=DTYPE)  # S in H_SB = S x B

    primitive_dim = 100
    spf_dim = 20

    # Spectrum function
    def spec_func(omega):
        if 0 < omega < omega0:
            return eta
        else:
            return 0.0

    # Define all Leaf tensors and hamiltonian we need
    h_list = []
    sys_leaf = Leaf(name='sys0')
    h_list.append([(sys_leaf, -1.0j * sys_hamiltonian)])

    ph_parameters = linear_discretization(spec_func, omega0, dof)
    if loc is not None:
        adj_pair = (ph_parameters[loc][0], ph_parameters[loc][1] * scale)
        ph_parameters[loc] = adj_pair
    leaves = []
    for n, (omega, g) in enumerate(ph_parameters, 1):
        ph = Phonon(primitive_dim, omega)
        ph_leaf = Leaf(name='ph{}'.format(n))
        leaves.append(ph_leaf)
        # hamiltonian ph part
        h_list.append([(ph_leaf, -1.0j * ph.hamiltonian)])
        # e-ph part
        op = ph.annihilation_operator + ph.creation_operator
        h_list.append([(ph_leaf, g * op), (sys_leaf, -1.0j * projector)])

    def ph_spf(n=0):
        n += 1
        return Tensor(name='spf{}'.format(n), axis=0)

    graph, root = huffman_tree(leaves, obj_new=ph_spf, n_branch=2)
    try:
        graph[root].insert(0, sys_leaf)
    except KeyError:
        ph_leaf = root
        root = Tensor()
        graph[root] = [sys_leaf, ph_leaf]
    finally:
        root.name = 'wfn'
        root.axis = None

    print(graph)
    stack = [root]
    while stack:
        parent = stack.pop()
        for child in graph[parent]:
            parent.link_to(parent.order, child, 0)
            if child in graph:
                stack.append(child)

    # Define the detailed parameters for the ML-MCTDH tree
    solver = MultiLayer(root, h_list)
    bond_dict = {}
    # Leaves
    for s, i, t, j in root.linkage_visitor():
        if t.name.startswith('sys'):
            bond_dict[(s, i, t, j)] = 2
        else:
            if isinstance(t, Leaf):
                bond_dict[(s, i, t, j)] = primitive_dim
            else:
                bond_dict[(s, i, t, j)] = spf_dim
    solver.autocomplete(bond_dict)
    # set initial root array
    a, b = 1.0, 1.0
    init_proj = np.array([[a, 0.0], [b, 0.0]]) / np.sqrt(a**2 + b**2)
    root_array = Tensor.partial_product(root.array, 0, init_proj, 1)
    root.set_array(root_array)

    # Define the computation details
    solver.ode_method = 'RK45'
    solver.snd_order = True
    solver.cmf_steps = 1
    root.is_normalized = True
    # Define the obersevable of interest
    logger.info('''# time/fs    rho00  rho01  rho10  rho11''')
    for time, _ in solver.propagator(
            steps=steps,
            ode_inter=Quantity(ode_inter, 'fs').value_in_au,
            split=True,
    ):
        t = Quantity(time).convert_to(unit='fs').value
        for tensor in root.visitor(axis=None):
            tensor.reset()
        rho = root.partial_env(0, proper=False)
        for tensor in root.visitor(axis=None):
            tensor.reset()
        flat_data = [t] + list(np.reshape(rho, -1))
        logger.info('{}    {}  {}  {}  {}'.format(*flat_data))