def test_outer_product(self):
   a = np.array([1, 2, 3])
   b = np.array([1, 2])
   res = ncon_interface.ncon([a, b], [(-1,), (-2,)])
   self.assertAllClose(res, np.kron(a, b).reshape((3, 2)))
   res = ncon_interface.ncon([a, a, a, a], [(0,), (0,), (1,), (1,)])
   self.assertEqual(res.numpy(), 196)
  def test_order_spec(self):
    a = tf.ones((2, 2))

    result = ncon_interface.ncon([a, a], [(-1, 0), (0, -2)], out_order=[-1, -2])
    self.assertAllClose(result, tf.ones((2, 2)) * 2)

    result = ncon_interface.ncon([a, a], [(-1, 0), (0, -2)], con_order=[0])
    self.assertAllClose(result, tf.ones((2, 2)) * 2)

    result = ncon_interface.ncon([a, a], [(-1, 0), (0, -2)],
                                 con_order=[0],
                                 out_order=[-1, -2])
    self.assertAllClose(result, tf.ones((2, 2)) * 2)
Exemple #3
0
def test_outer_product_2(backend):
  np.random.seed(10)
  a = np.random.rand(10, 100)
  b = np.random.rand(8)
  res = ncon_interface.ncon([a, b], [(-1, -2), (-3,)],
                            out_order=[-2, -1, -3],
                            backend=backend)
  exp = np.einsum('ij,k->jik', a, b)
  np.testing.assert_allclose(res, exp)
 def test_invalid_order(self):
   a = tf.ones((2, 2))
   with self.assertRaises(ValueError):
     ncon_interface.ncon([a, a], [(0, 1), (1, 0)], con_order=[1, 2])
   with self.assertRaises(ValueError):
     ncon_interface.ncon([a, a], [(0, 1), (1, 0)], out_order=[-1])
   with self.assertRaises(ValueError):
     ncon_interface.ncon([a, a], [('i1', 'i2'), ('i1', 'i2')],
                         con_order=['i1'],
                         out_order=[])
   with self.assertRaises(ValueError):
     ncon_interface.ncon([a, a], [('i1', 'i2'), ('i1', 'i2')],
                         con_order=['i1', 'i2'],
                         out_order=['i1'])
   with self.assertRaises(ValueError):
     ncon_interface.ncon([a, a], [('i1', 'i2'), ('i1', 'i2')],
                         con_order=['i1', 'i1', 'i2'],
                         out_order=[])
Exemple #5
0
def test_outer_product_2_mixed_labels(backend):
  np.random.seed(10)
  a = np.random.rand(10, 100)
  b = np.random.rand(8)
  res = ncon_interface.ncon([a, b], [(-1, '-hi'), ('-ho',)],
                            out_order=['-hi', -1, '-ho'],
                            backend=backend)
  exp = np.einsum('ij,k->jik', a, b)
  np.testing.assert_allclose(res, exp)
Exemple #6
0
def test_node_small_matmul(backend):
  np.random.seed(10)
  t1 = np.random.randn(2, 2)
  t2 = np.random.randn(2, 2)

  a = Tensor(t1, backend=backend)
  b = Tensor(t2, backend=backend)
  res = ncon_interface.ncon([a, b], [(1, -1), (1, -2)], backend=backend)
  np.testing.assert_allclose(res.array, t1.transpose() @ t2)
Exemple #7
0
def test_contraction_mixed_labels(backend):
  np.random.seed(10)
  a = np.random.randn(2, 2, 2)
  res = ncon_interface.ncon([a, a, a], [(-1, 'rick', 2), ('rick', 2, 'morty'),
                                        ('morty', -2, -3)],
                            backend=backend)
  res_np = a.reshape((2, 4)) @ a.reshape((4, 2)) @ a.reshape((2, 4))
  res_np = res_np.reshape((2, 2, 2))
  np.testing.assert_allclose(res, res_np)
Exemple #8
0
def test_partial_traces(backend):
  np.random.seed(10)
  a = np.random.rand(4, 4, 4, 4)
  res = ncon_interface.ncon([a, a], [(-1, 1, 1, 3), (2, -2, 2, 3)],
                            backend=backend)
  t1 = np.trace(a, axis1=1, axis2=2)
  t2 = np.trace(a, axis1=0, axis2=2)
  exp = np.tensordot(t1, t2, ([1], [1]))
  np.testing.assert_allclose(res, exp)
Exemple #9
0
def test_batched_matmul_3(backend):
  np.random.seed(10)
  batchsize = 10
  a = np.random.randn(2, 4, 4, batchsize)
  b = np.random.randn(4, 3, batchsize, 5)
  c = np.random.randn(batchsize, 5, 4)
  res = ncon_interface.ncon([a, b, c], [(-1, 1, 2, 4), (1, -2, 4, 3),
                                        (4, 3, 2)],
                            backend=backend)
  exp = np.einsum('abck,bdke,kec->ad', a, b, c)
  np.testing.assert_allclose(res, exp)

  res = ncon_interface.ncon([a, b, c], [(-1, 1, 2, 4), (1, -2, 4, 3),
                                        (4, 3, 2)],
                            out_order=[-2, -1],
                            backend=backend)
  exp = np.einsum('abck,bdke,kec->da', a, b, c)
  np.testing.assert_allclose(res, exp)
def test_node_contraction(backend):
  tensor = np.random.randn(2, 2, 2)
  a = Node(tensor, backend=backend)
  res = ncon_interface.ncon([a, a, a], [(-1, 1, 2), (1, 2, 3), (3, -2, -3)],
                            backend=backend)
  res_np = tensor.reshape((2, 4)) @ tensor.reshape((4, 2)) @ tensor.reshape(
      (2, 4))
  res_np = res_np.reshape((2, 2, 2))
  np.testing.assert_allclose(res.tensor, res_np)
Exemple #11
0
 def compute_energy(self):
     self.mps.position(0)  #move center position to the left end
     self.compute_right_envs()
     return ncon([
         self.add_right_layer(self.right_envs[0], self.mps.tensors[0],
                              self.mpo.tensors[0]),
         self.left_envs[0],
     ], [[1, 2, 3], [1, 2, 3]],
                 backend=self.backend.name).item()
Exemple #12
0
def test_invalid_order():
    a = tf.ones((2, 2))
    with pytest.raises(ValueError):
        ncon_interface.ncon([a, a], [(1, 2), (2, 1)], con_order=[2, 3])
    with pytest.raises(ValueError):
        ncon_interface.ncon([a, a], [(1, 2), (2, 1)], out_order=[-1])
    with pytest.raises(ValueError):
        ncon_interface.ncon([a, a], [('i1', 'i2'), ('i1', 'i2')],
                            con_order=['i1'],
                            out_order=[])
    with pytest.raises(ValueError):
        ncon_interface.ncon([a, a], [('i1', 'i2'), ('i1', 'i2')],
                            con_order=['i1', 'i2'],
                            out_order=['i1'])
    with pytest.raises(ValueError):
        ncon_interface.ncon([a, a], [('i1', 'i2'), ('i1', 'i2')],
                            con_order=['i1', 'i1', 'i2'],
                            out_order=[])
Exemple #13
0
def test_batched_matmul_1(backend):
  np.random.seed(10)
  a = np.random.randn(10, 11, 100)
  b = np.random.randn(11, 100, 12)
  res = ncon_interface.ncon([a, b], [(-1, 1, -3), (1, -3, -2)], backend=backend)
  exp = np.einsum('ijk,jkm->imk', a, b)
  np.testing.assert_allclose(res, exp)

  res = ncon_interface.ncon([a, b], [(-1, 1, -3), (1, -3, -2)],
                            out_order=[-2, -1, -3],
                            backend=backend)
  exp = np.einsum('ijk,jkm->mik', a, b)
  np.testing.assert_allclose(res, exp)

  res = ncon_interface.ncon([a, b], [(-1, 1, -3), (1, -3, -2)],
                            out_order=[-3, -2, -1],
                            backend=backend)
  exp = np.einsum('ijk,jkm->kmi', a, b)
  np.testing.assert_allclose(res, exp)
def doApplyMPO(psi,p,Larr,Marr,Rarr,c):
    """ function for applying MPO to state """
    summ = 0
    Q = len(Marr)
    for i in range(Q):
        summ += c[i]*ncon([psi.reshape(Larr[i][p].shape[2],Marr[i][p].shape[3],Marr[i][p+1].shape[3],Rarr[i][p+1].shape[2]),Larr[i][p],Marr[i][p],Marr[i][p+1],Rarr[i][p+1]],
                       [[1,3,5,7],[2,-1,1],[2,4,-2,3],[4,6,-3,5],[6,-4,7]]).reshape( 
                               Larr[i][p].shape[2]*Marr[i][p].shape[3]*Marr[i][p+1].shape[3]*Rarr[i][p+1].shape[2])
    
    return summ
def test_node_order_spec(backend):
    node = Node(np.ones((2, 2)), backend=backend)
    result = ncon_interface.ncon([node, node], [(-1, 1), (1, -2)],
                                 out_order=[-1, -2],
                                 backend=backend)

    np.testing.assert_allclose(result.tensor, np.ones((2, 2)) * 2)
    result = ncon_interface.ncon([node, node], [(-1, 1), (1, -2)],
                                 con_order=[1],
                                 backend=backend)

    np.testing.assert_allclose(result.tensor, np.ones((2, 2)) * 2)

    result = ncon_interface.ncon([node, node], [(-1, 1), (1, -2)],
                                 con_order=[1],
                                 out_order=[-1, -2],
                                 backend=backend)

    np.testing.assert_allclose(result.tensor, np.ones((2, 2)) * 2)
def test_order_spec(backend):
    a = np.ones((2, 2))
    result = ncon_interface.ncon([a, a], [(-1, 1), (1, -2)],
                                 out_order=[-1, -2],
                                 backend=backend)
    np.testing.assert_allclose(result, np.ones((2, 2)) * 2)

    result = ncon_interface.ncon([a, a], [(-1, 1), (1, -2)],
                                 con_order=[1],
                                 backend=backend)

    np.testing.assert_allclose(result, np.ones((2, 2)) * 2)

    result = ncon_interface.ncon([a, a], [(-1, 1), (1, -2)],
                                 con_order=[1],
                                 out_order=[-1, -2],
                                 backend=backend)

    np.testing.assert_allclose(result, np.ones((2, 2)) * 2)
def test_node_small_matmul_mixed_labels(backend):
    np.random.seed(10)
    t1 = np.random.randn(2, 2)
    t2 = np.random.randn(2, 2)

    a = Node(t1, backend=backend)
    b = Node(t2, backend=backend)

    res = ncon_interface.ncon([a, b], [('hi', -1), ('hi', '-ho')],
                              backend=backend)
    np.testing.assert_allclose(res.tensor, t1.transpose() @ t2)
Exemple #18
0
def test_node_contraction_mixed_labels(backend):
  np.random.seed(10)
  tensor = np.random.randn(2, 2, 2)
  a = Tensor(tensor, backend=backend)
  res = ncon_interface.ncon([a, a, a], [(-1, 'rick', 2), ('rick', 2, 'morty'),
                                        ('morty', -2, -3)],
                            backend=backend)
  res_np = tensor.reshape((2, 4)) @ tensor.reshape((4, 2)) @ tensor.reshape(
      (2, 4))
  res_np = res_np.reshape((2, 2, 2))
  np.testing.assert_allclose(res.array, res_np)
def test_node_outer_product_2_mixed_labels(backend):
    np.random.seed(10)
    t1 = np.random.rand(10, 100)
    t2 = np.random.rand(8)
    a = Node(t1, backend=backend)
    b = Node(t2, backend=backend)

    res = ncon_interface.ncon([a, b], [(-1, '-hi'), ('-ho', )],
                              out_order=['-hi', -1, '-ho'],
                              backend=backend)
    exp = np.einsum('ij,k->jik', t1, t2)
    np.testing.assert_allclose(res.tensor, exp)
def test_node_outer_product_2(backend):
    np.random.seed(10)
    t1 = np.random.rand(10, 100)
    t2 = np.random.rand(8)
    a = Node(t1, backend=backend)
    b = Node(t2, backend=backend)

    res = ncon_interface.ncon([a, b], [(-1, -2), (-3, )],
                              out_order=[-2, -1, -3],
                              backend=backend)
    exp = np.einsum('ij,k->jik', t1, t2)
    np.testing.assert_allclose(res.tensor, exp)
Exemple #21
0
def test_ncon_vs_backend(dtype, backend):
    shape = (4, 3)
    dtype = testing_utils.np_dtype_to_backend(backend, dtype)
    testing_utils.check_contraction_dtype(backend, dtype)
    tensor1 = tensornetwork.ones(shape, backend=backend, dtype=dtype)
    tensor2 = tensornetwork.ones(shape, backend=backend, dtype=dtype)
    tensor3 = tensornetwork.ones(shape, backend=backend, dtype=dtype)
    tensors = [tensor1, tensor2, tensor3]
    arrays = [tensor1.array, tensor2.array, tensor3.array]
    idxs = [[1, -1], [1, 2], [-2, 2]]
    result = ncon(tensors, idxs, backend=backend)
    old_result = tensornetwork.ncon(arrays, idxs, backend=backend)
    np.testing.assert_allclose(old_result, result.array)
Exemple #22
0
def test_ncon_builder(backend):
  a, _ = testing_utils.safe_randn((2, 2, 2), backend, np.float32)
  b, _ = testing_utils.safe_randn((2, 2, 2), backend, np.float32)
  c, _ = testing_utils.safe_randn((2, 2, 2), backend, np.float32)
  tmp = a(2, 1, -1)
  assert tmp.tensors[0] is a
  assert tmp.axes[0] == [2, 1, -1]
  builder = a(2, 1, -1) @ b(2, 3, -2) @ c(1, 3, -3)
  assert builder.tensors == [a, b, c]
  assert builder.axes == [[2, 1, -1], [2, 3, -2], [1, 3, -3]]
  np.testing.assert_allclose(
      ncon_interface.ncon(
          [a, b, c], 
          [[2, 1, -1], [2, 3, -2], [1, 3, -3]], 
          backend=backend).array,
      ncon_interface.finalize(builder).array)
Exemple #23
0
 def apply_one_site_gate(self, gate: Tensor, site: int) -> None:
   """Apply a one-site gate to an MPS. This routine will in general destroy
   any canonical form of the state. If a canonical form is needed, the user
   can restore it using `FiniteMPS.position`
   Args:
     gate: a one-body gate
     site: the site where the gate should be applied
   """
   if len(gate.shape) != 2:
     raise ValueError('rank of gate is {} but has to be 2'.format(
         len(gate.shape)))
   if site < 0 or site >= len(self):
     raise ValueError('site = {} is not between 0 <= site < N={}'.format(
         site, len(self)))
   self.tensors[site] = ncon([gate, self.tensors[site]],
                             [[-2, 1], [-1, 1, -3]],
                             backend=self.backend.name)
Exemple #24
0
def createFactorTable_Su2CoarseGrain_2To1Site(
        W: 'list of pairs of Su2Tensors', wd: Su2Tensor, tableFileName: str) -> dict:
    """
    (Precomputation.) Creates the factors and compatible chargesectors for the function Su2CoarseGrain_2To1Site()
    W: a list of pairs of SU(2) tensors
    wd: a SU(2) tensor (the isometry that blocks 2 lattice sites)
    tableFileName: file name to store the created factor table
    """

    FactorTable = dict() # Dictionary from fusion trees to factors
    for k in range(len(W)):
        w1 = W[k][0]
        w2 = W[k][1]
        for c1 in w2.getAllBlocks():
            for c2 in w1.getAllBlocks():
                if c2[total] != c1[left]:
                    continue
                for c3 in wd.getAllBlocks():
                    if c2[right] != c3[left] or c1[right] != c3[right] or not Su2Engine.compatible(c2[left], c3[total],\
                                                                                                             c1[total]):
                        continue
                    for c4 in wd.getAllBlocks():
                        if c4[total] != c3[total]:
                            continue
                        for c5 in w1.getAllBlocks():
                            if c5[right] != c4[left] or c5[left] != c2[left] or not Su2Engine.compatible(c5[total],\
                                                                                                c4[right],c1[total]):
                                continue
                            for c6 in w2.getAllBlocks():
                                if c6[left] != c5[total] or c6[right] != c4[right] or c6[total] != c1[total]:
                                    continue

                                C1 = Su2Engine.createCGtensor(c1[left], c1[right], c1[total])
                                C2 = Su2Engine.createCGtensor(c2[left], c2[right], c2[total])
                                C3 = Su2Engine.createCGtensor(c3[left], c3[right], c3[total])
                                C4 = Su2Engine.createCGtensor(c4[left], c4[right], c4[total])
                                C5 = Su2Engine.createCGtensor(c5[left], c5[right], c5[total])
                                C6 = Su2Engine.createCGtensor(c6[left], c6[right], c6[total])
                                Cmat = ncon([C1,C2,C3,C4,C5,C6],[[1,3,-1],[7,2,1],[2,3,8],[5,6,8],[7,5,4],[4,6,-2]])
                                FactorTable[FusionTree((c1[total],c1[left],c2[left],c2[right],c1[right],c3[total],\
                                                                           c4[left],c4[right],c5[total]))] = Cmat[0][0]

    np.save(tableFileName, FactorTable)
    return FactorTable
Exemple #25
0
def Su2CoarseGrain_1To1site(
    w: Su2Tensor, h: Su2Tensor) -> Su2Tensor:
    """
    Coarse-grains (blocks) 1-site operator h through isometry w.
    w: the blocking isometry
    h: the 1-site SU(2)-symmetric operator
    """

    hh = Su2Tensor(h.getIndices()) # the coarse-grained hamiltonian. Even though h is a 4-index tensor it is
                                   # stored as a 2-index matrix. So indices of h are the blocked 2-site indices
    wBlocks = w.getAllBlocks() # a dictionary {FusionTree:block}
    hBlocks = h.getAllBlocks() # a dictionary {FusionTree:block}
    for ft in wBlocks:
        ch = FusionTree((ft[1],ft[1]))
        if not ch in hBlocks:
            continue
        temp = ncon([wBlocks[ft],hBlocks[ch],wBlocks[ft]],[[-1, 1, 3],[1, 2],[-2, 2, 3]])
        hh.addblock(FusionTree((ft[0],ft[0])),temp)

    return hh
Exemple #26
0
def test_ncon_invalid_backends(dtype, backend):
    backend_names = set(["jax", "numpy", "tensorflow", "pytorch"])
    this_name = set([backend])
    other_backend_names = list(backend_names - this_name)
    shape = (4, 3)
    dtype1 = testing_utils.np_dtype_to_backend(backend, dtype)
    tensor1 = tensornetwork.ones(shape, backend=backend, dtype=dtype1)
    for other_backend in other_backend_names:
        dtype2 = testing_utils.np_dtype_to_backend(other_backend, dtype)
        tensor2 = tensornetwork.ones(shape,
                                     backend=other_backend,
                                     dtype=dtype2)
        for other_other_backend in backend_names:
            dtype3 = testing_utils.np_dtype_to_backend(other_other_backend,
                                                       dtype)
            tensor3 = tensornetwork.zeros(shape,
                                          backend=other_other_backend,
                                          dtype=dtype3)
            tensors = [tensor1, tensor2, tensor3]
            idxs = [[1, -1], [1, 2], [-2, 2]]
            with pytest.raises(ValueError):
                _ = ncon(tensors, idxs)
Exemple #27
0
def test_left_envs_all_sites(backend_dtype_values):
    backend = backend_factory.get_backend(backend_dtype_values[0])
    dtype = backend_dtype_values[1]

    D, d, N = 3, 2, 5
    tensors = [np.ones((1, d, D), dtype=dtype)
               ] + [np.ones((D, d, D), dtype=dtype)
                    for _ in range(N - 2)] + [np.ones((D, d, 1), dtype=dtype)]
    mps = FiniteMPS(tensors,
                    center_position=N // 2,
                    backend=backend_dtype_values[0],
                    canonicalize=True)
    l = backend.convert_to_tensor(np.ones((1, 1), dtype=dtype))
    exp = {}
    for n, t in enumerate(mps.tensors):
        exp[n] = l
        l = ncon([t, l, t], [[1, 2, -1], [1, 3], [3, 2, -2]], backend=backend)
    envs = mps.left_envs(sites=range(N))
    assert list(envs.keys()) == list(range(N))
    for n in range(N):
        expected = exp[n]
        actual = envs[n]
        np.testing.assert_array_almost_equal(expected, actual)
def test_small_matmul(backend):
    a = np.random.randn(2, 2)
    b = np.random.randn(2, 2)
    res = ncon_interface.ncon([a, b], [(1, -1), (1, -2)], backend=backend)
    np.testing.assert_allclose(res, a.transpose() @ b)
def test_trace(backend):
    a = np.ones((2, 2))
    res = ncon_interface.ncon([a], [(1, 1)], backend=backend)
    np.testing.assert_allclose(res, 2)
def test_output_order(backend):
    a = np.random.randn(2, 2)
    res = ncon_interface.ncon([a], [(-2, -1)], backend=backend)
    np.testing.assert_allclose(res, a.transpose())
def test_out_of_order_contraction(backend):
    a = np.ones((2, 2, 2))
    with pytest.warns(UserWarning, match='Suboptimal ordering'):
        ncon_interface.ncon([a, a, a], [(-1, 1, 3), (1, 3, 2), (2, -2, -3)],
                            backend=backend)
 def test_invalid_network(self):
   a = tf.ones((2, 2))
   with self.assertRaises(ValueError):
     ncon_interface.ncon([a, a], [(0, 1), (1, 0), (0, 1)])
   with self.assertRaises(ValueError):
     ncon_interface.ncon([a, a], [(0, 1), (1, 1)])
   with self.assertRaises(ValueError):
     ncon_interface.ncon([a, a], [(0, 1), (2, 0)])
   with self.assertRaises(ValueError):
     ncon_interface.ncon([a, a], [(0, 1), (1, 0.1)])
   with self.assertRaises(ValueError):
     ncon_interface.ncon([a, a], [(0, 1), (1, 't')])
   with self.assertRaises(ValueError):
     ncon_interface.ncon([a, a], [(0,), (0, 1)])
 def test_order_spec_noninteger(self):
   a = tf.ones((2, 2))
   result = ncon_interface.ncon([a, a], [('o1', 'i'), ('i', 'o2')],
                                con_order=['i'],
                                out_order=['o1', 'o2'])
   self.assertAllClose(result, tf.ones((2, 2)) * 2)
 def test_sanity_check(self):
   result = ncon_interface.ncon([tf.ones(
       (2, 2)), tf.ones((2, 2))], [(-1, 0), (0, -2)])
   self.assertAllClose(result, tf.ones((2, 2)) * 2)
 def test_contraction(self):
   a = np.random.randn(2, 2, 2)
   res = ncon_interface.ncon([a, a, a], [(-1, 0, 1), (0, 1, 2), (2, -2, -3)])
   res_np = a.reshape((2, 4)) @ a.reshape((4, 2)) @ a.reshape((2, 4))
   res_np = res_np.reshape((2, 2, 2))
   self.assertAllClose(res, res_np)
 def test_small_matmul(self):
   a = np.random.randn(2, 2)
   b = np.random.randn(2, 2)
   res = ncon_interface.ncon([a, b], [(0, -1), (0, -2)])
   self.assertAllClose(res, a.transpose() @ b)
 def test_out_of_order_contraction(self):
   a = tf.ones((2, 2, 2))
   with self.assertRaises(ValueError):
     ncon_interface.ncon([a, a, a], [(-1, 0, 2), (0, 2, 1), (1, -2, -3)])
def test_sanity_check(backend):
    result = ncon_interface.ncon([np.ones(
        (2, 2)), np.ones((2, 2))], [(-1, 1), (1, -2)],
                                 backend=backend)
    np.testing.assert_allclose(result, np.ones((2, 2)) * 2)
 def test_trace(self):
   a = tf.ones((2, 2))
   res = ncon_interface.ncon([a], [(0, 0)])
   self.assertEqual(res.numpy(), 2)
def test_invalid_network(backend):
    a = np.ones((2, 2))
    with pytest.raises(ValueError):
        ncon_interface.ncon([a, a], [(1, 2), (2, 1), (1, 2)], backend=backend)
    with pytest.raises(ValueError):
        ncon_interface.ncon([a, a], [(1, 2), (2, 2)], backend=backend)
    with pytest.raises(ValueError):
        ncon_interface.ncon([a, a], [(1, 2), (3, 1)], backend=backend)
    with pytest.raises(ValueError):
        ncon_interface.ncon([a, a], [(1, 2), (2, 0.1)], backend=backend)
    with pytest.raises(ValueError):
        ncon_interface.ncon([a, a], [(1, 2), (2, 't')], backend=backend)
    with pytest.raises(ValueError):
        ncon_interface.ncon([a, a], [(0, 1), (1, 0)], backend=backend)
    with pytest.raises(ValueError):
        ncon_interface.ncon([a, a], [(1, ), (1, 2)], backend=backend)
 def test_output_order(self):
   a = np.random.randn(2, 2)
   res = ncon_interface.ncon([a], [(-2, -1)])
   self.assertAllClose(res, a.transpose())