快速上手#

安装#

  • x64 Linux

pip install tensorcircuit

is in general enough. Either pip from conda or other python env managers is fine.

Since there are many optional packages for various features, the users may need to install more pip packages when required.

  • For Linux with Nvidia GPU,

please refer to the GPU aware installation guide of corresponding machine learning frameworks: TensorFlow, Jax, or PyTorch.

Docker is also recommended (especially Linux + Nvidia GPU setup):

sudo docker run -it --network host --gpus all tensorcircuit/tensorcircuit.

For more details on docker setup, please refer to docker readme.

Overall, the installation of TensorCircuit is simple, since it is purely in Python and hence very portable. As long as the users can take care of the installation of ML frameworks on the corresponding system, TensorCircuit will work as expected.

To debug the installation issue or report bugs, please check the environment information by tc.about().

注解

We also provide a nightly build of tensorcircuit via PyPI which can be accessed by pip uninstall tensorcircuit, then pip install tensorcircuit-nightly

电路对象#

TensorCircuit的基本对象是 tc.Circuit

用量子比特数(n) c=tc.Circuit(n) 来初始化电路。

输入状态:

电路的默认输入函数是 \(\vert 0^n \rangle\) 。可以通过直接输入输入状态向量 w 将其更改为其他波函数: c=tc.Circuit(n, inputs=w)

也可以将矩阵乘积状态作为电路的输入状态,但我们将矩阵乘积状态/矩阵乘积算子的使用留待后续讲解。

量子门:

我们可以将门应用于电路对象。 例如,使用 c.H(1)c.rx(2, theta=0.2),我们可以将 Hadamard 门应用于量子比特1 (基于0)或将 Rx 门应用于量子比特2 \(e^{-i\theta/2 X}\)

同样的规则亦适用于多量子比特门,例如 c.cnot(0, 1)

这些量子门也是高度可定制的,下面是两个例子

  • c.exp1(0, 1, unitary=m, theta=0.2) 用于任何矩阵 m 的指数门 \(e^{i\theta m}\),只要 m 满足 \(m^2=1\)

  • c.any(0, 1, unitary=m) 在电路上作用任意的幺正量子门。

这两个例子很灵活,支持任意数量的量子比特上的门。

测量与期望

从电路对象中获取输出的最直接的方法是通过 c.state() 以向量形式获取输出波函数。

对于位串采样,我们有 c.perfect_sampling(),它返回位串和相应的概率幅度。

要测量部分量子比特,我们可以使用 c.measure(0, 1),如果我们想知道测量的结果的对应概率,可以尝试 c.measure(0, 1, with_prob=True)。 测量 API 在默认情况下是不可即时编译的 ,但我们也有一个可即时编译的版本,如 c.measure_jit(0, 1)

测量和采样使用了基于张量网络的高级算法,因此不需要任何相关知识或者空间来获取全波函数。

请看下面的例子:

K = tc.set_backend("jax")
@K.jit
def sam(key):
    K.set_random_state(key)
    n = 50
    c = tc.Circuit(n)
    for i in range(n):
        c.H(i)
    return c.perfect_sampling()

sam(jax.random.PRNGKey(42))
sam(jax.random.PRNGKey(43))

为了计算局部可观察量的期望值,我们有 c.expectation([tc.gates.z(), [0]], [tc.gates.z(), [1]]) 对应的期望为 \(\langle Z_0Z_1 \rangle\) 时,或 c.expectation([tc.gates.x(), [0]]) 对应的期望为 :math:`langle X_0 rangle`时.

因为可以在几个量子比特上测量一个 m,这种计算期望值的 API 相当灵活:c.expectation([m, [0, 1, 2]])

我们还可以提取整个电路下面的幺正矩阵,如下所示:

>>> n = 2
>>> c = tc.Circuit(n, inputs=tc.backend.eye(2**n))
>>> c.X(1)
>>> tc.backend.reshapem(c.state())
array([[0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],
    [1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
    [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],
    [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j]], dtype=complex64)

电路可视化

我们目前支持 tc.Circuit 与 Qiskit QuantumCircuit 对象之间的互相转换。

导出到 Qiskit(可能用于进一步的硬件实验、编译和可视化):c.to_qiskit()

Import from Qiskit: c = tc.Circuit.from_qiskit(QuantumCircuit, n). Parameterized Qiskit circuit is supported by passing the parameters to the binding_parameters argument of the from_qiskit function, similar to the assign_parameters function in Qiskit.

电路可视化

c.vis_tex() 可以基于 quantikz package 生成用于电路可视化的 tex 代码。

还有一些自动辅助函数可以直接从 tex 代码生成图形,但它们需要在环境中进行额外安装。

render_pdf(tex) 函数需要在本地完全安装 LaTeX。 在 Jupyter 环境中,我们可能会偏好 render_pdf(tex, notebook=True) 来返回 jpg 图形,这需要安装 wand magicwand 库,请参阅 这里

从 Qiskit 导入:c = tc.Circuit.from_qiskit(QuantumCircuit, n) 或者因为我们可以轻松地将 tc.Circuit 转换为 QuantumCircuit,我们有一个简单的管道来首先转换 tc.Circuit 为 Qiskit,然后调用 Qiskit 中内置的可视化。 也就是说,我们有 c.draw() API。

电路中间表示:

TensorCircuit 提供自己的中间表示是元素是字典的列表。此中间表示可进一步用于运行编译、生成序列化 qasm 或渲染电路图。

中间表示以列表形式给出,每个元素都是一个字典,其中包含应用于电路的一个量子门的信息。 注意字典中的 gate atrr 实际上是一个返回此量子门的节点的 python 函数。

>>> c = tc.Circuit(2)
>>> c.cnot(0, 1)
>>> c.crx(1, 0, theta=0.2)
>>> c.to_qir()
[{'gate': cnot, 'index': (0, 1), 'name': 'cnot', 'split': None}, {'gate': crx, 'index': (1, 0), 'name': 'crx', 'split': None, 'parameters': {'theta': 0.2}}]

We can also create new copied circuit via c.copy() which internally utilize the qir.

编程范式#

TensorCircuit 最常见的情况和最典型的编程范式是评估电路的输出以及相应的量子梯度,这在变分量子算法中很常见。

import tensorcircuit as tc

K = tc.set_backend("tensorflow")

n = 1


def loss(params, n):
    c = tc.Circuit(n)
    for i in range(n):
        c.rx(i, theta=params[0, i])
    for i in range(n):
        c.rz(i, theta=params[1, i])
    loss = 0.0
    for i in range(n):
        loss += c.expectation([tc.gates.z(), [i]])
    return K.real(loss)


vgf = K.jit(K.value_and_grad(loss), static_argnums=1)
params = K.implicit_randn([2, n])
print(vgf(params, n))  # get the quantum loss and the gradient

Also for a non-quantum example (linear regression) demonstrating the backend agnostic feature, variables with pytree support, AD/jit/vmap usage, and variational optimization loops. Please refer to the example script: linear regression example. This example might be more friendly to the machine learning community since it is purely classical while also showcasing the main features and paradigms of tensorcircuit.

如果用户无意以与后端无关的方式维护应用程序代码,则可以更方便地使用用于机器学习框架的 API 并将其与 TensorCircuit API 交替使用。

import tensorcircuit as tc
import tensorflow as tf

K = tc.set_backend("tensorflow")

n = 1


def loss(params, n):
    c = tc.Circuit(n)
    for i in range(n):
        c.rx(i, theta=params[0, i])
    for i in range(n):
        c.rz(i, theta=params[1, i])
    loss = 0.0
    for i in range(n):
        loss += c.expectation([tc.gates.z(), [i]])
    return tf.math.real(loss)

def vgf(params, n):
    with tf.GradientTape() as tape:
        tape.watch(params)
        l = loss(params, n)
    return l, tape.gradient(l, params)

vgf = tf.function(vgf)
params = tf.random.normal([2, n])
print(vgf(params, n))  # get the quantum loss and the gradient

自动微分、即时编译和矢量化并行#

关于自动微分、即时编译和向量并行化,请参考 Jax 文档

TensorCircuit 中的相关 API 设计与 Jax 中的函数式编程的设计模式密切相关,但是略有不同。因此,我们强烈建议用户学习一些有关 Jax 的基础知识,无论他们打算使用哪种机器学习后端。

自动微分支持

梯度、矢量雅可比乘积、自然梯度、 Jacobian 矩阵和 Hessian 矩阵。自动微分是所有现代机器学习库的基础。

自动微分支持

参数化的量子电路可以在瞬间完成运行。如果电路将得到多次运行,请始终使用即时编译,它可以大大提高仿真速度,减少两到三个数量级的运行时间。但也要小心,用户需要熟悉 即时编译,否则,即时编译的函数可能会返回意外结果或每次在点击时都重新编译(浪费大量时间)。要了解更多关于即时编译机制的信息,可以参考关于 tf.functionjax.jit 的文档或博客,即使这两者仍然存在细微差别。

自动微分支持

输入、参数、测量、电路结构、蒙特卡洛噪声都可以并行测算。 要了解有关矢量并行化机制的更多信息,可以参考 tf.vectorized_mapjax.vmap 上的文档或博客。

后端无关特性#

TensorCircuit 支持 TensorFlow、Jax 和 PyTorch 后端。 我们建议使用 TensorFlow 或 Jax 后端,因为 PyTorch 缺乏高级 jit 和 vmap 功能。

后端可以设置为 K=tc.set_backend("jax")K``作为常规机器学习框架的全套API的后端,也可以通过``tc .backend 被访问。

>>> import tensorcircuit as tc
>>> K = tc.set_backend("tensorflow")
>>> K.ones([2,2])
<tf.Tensor: shape=(2, 2), dtype=complex64, numpy=
array([[1.+0.j, 1.+0.j],
    [1.+0.j, 1.+0.j]], dtype=complex64)>
>>> tc.backend.eye(3)
<tf.Tensor: shape=(3, 3), dtype=complex64, numpy=
array([[1.+0.j, 0.+0.j, 0.+0.j],
    [0.+0.j, 1.+0.j, 0.+0.j],
    [0.+0.j, 0.+0.j, 1.+0.j]], dtype=complex64)>
>>> tc.set_backend("jax")
<tensorcircuit.backends.jax_backend.JaxBackend object at 0x7fb00e0fd6d0>
>>> tc.backend.name
'jax'
>>> tc.backend.implicit_randu()
WARNING:absl:No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)
DeviceArray([0.7400521], dtype=float32)

The supported APIs in the backend come from two sources, one part is implemented in TensorNetwork package and the other part is implemented in TensorCircuit package. To see all the backend agnostic APIs, try:

>>> [s for s in dir(tc.backend) if not s.startswith("_")]
['abs',
'acos',
'acosh',
'addition',
'adjoint',
'arange',
'argmax',
'argmin',
'asin',
'asinh',
'atan',
'atan2',
'atanh',
'broadcast_left_multiplication',
'broadcast_right_multiplication',
'cast',
'cholesky',
'concat',
'cond',
'conj',
'convert_to_tensor',
'coo_sparse_matrix',
'coo_sparse_matrix_from_numpy',
'copy',
'cos',
'cosh',
'cumsum',
'deserialize_tensor',
'device',
'device_move',
'diagflat',
'diagonal',
'divide',
'dtype',
'eigh',
'eigs',
'eigsh',
'eigsh_lanczos',
'eigvalsh',
'einsum',
'eps',
'exp',
'expm',
'eye',
'from_dlpack',
'g',
'gather1d',
'get_random_state',
'gmres',
'grad',
'hessian',
'i',
'imag',
'implicit_randc',
'implicit_randn',
'implicit_randu',
'index_update',
'inv',
'is_sparse',
'is_tensor',
'item',
'jacbwd',
'jacfwd',
'jacrev',
'jit',
'jvp',
'kron',
'left_shift',
'log',
'matmul',
'max',
'mean',
'min',
'minor',
'mod',
'multiply',
'name',
'norm',
'numpy',
'one_hot',
'onehot',
'ones',
'optimizer',
'outer_product',
'pivot',
'power',
'probability_sample',
'qr',
'randn',
'random_split',
'random_uniform',
'real',
'relu',
'reshape',
'reshape2',
'reshapem',
'reverse',
'right_shift',
'rq',
'scatter',
'searchsorted',
'serialize_tensor',
'set_random_state',
'shape_concat',
'shape_prod',
'shape_tensor',
'shape_tuple',
'sigmoid',
'sign',
'sin',
'sinh',
'size',
'sizen',
'slice',
'softmax',
'solve',
'sparse_dense_matmul',
'sparse_shape',
'sqrt',
'sqrtmh',
'stack',
'stateful_randc',
'stateful_randn',
'stateful_randu',
'std',
'stop_gradient',
'subtraction',
'sum',
'svd',
'switch',
'tan',
'tanh',
'tensordot',
'tile',
'to_dense',
'to_dlpack',
'trace',
'transpose',
'tree_flatten',
'tree_map',
'tree_unflatten',
'unique_with_counts',
'value_and_grad',
'vectorized_value_and_grad',
'vjp',
'vmap',
'vvag',
'zeros']

转换 dtype#

TensorCircuit 支持使用 32/64 bit 精确度的模拟。默认的 dtype 是 32-bit 的 "complex64"。可以通过 tc.set_dtype("complex128") 把 dtype 改为 "complex 128" 。

tc.dtypestr 总会返回当前的 dtype 字符串: 不是 "complex64" 就是 "complex128".

设置 contractor#

TensorCircuit 是一个基于张量网络收缩的量子电路模拟器。 contractor 用于搜索电路张量网络的最佳收缩路径。

有各种第三方包提供的高级 contractor ,例如 opt-einsumcotengra

opt-einsum 随 TensorNetwork 软件包一起。如要使用 cotengra,则需要 pip 安装它; 还建议安装 cotengra 随 kahypar 一起使用。

一些设置案例:

import tensorcircuit as tc

# 1. cotengra contractors, have better and consistent performance for large circuit simulation
import cotengra as ctg

optr = ctg.ReusableHyperOptimizer(
    methods=["greedy", "kahypar"],
    parallel=True,
    minimize="flops",
    max_time=120,
    max_repeats=4096,
    progbar=True,
)
tc.set_contractor("custom", optimizer=optr, preprocessing=True)
# by preprocessing set as True, tensorcircuit will automatically merge all single-qubit gates into entangling gates

# 2.  RandomGreedy contractor
tc.set_contractor("custom_stateful", optimizer=oem.RandomGreedy, max_time=60, max_repeats=128, minimize="size")

# 3. state simulator like contractor provided by tensorcircuit, maybe better when there is ring topology for two-qubit gate layout
tc.set_contractor("plain-experimental")

For advanced configurations on cotengra contractors, please refer to cotengra doc and more fancy examples can be found at contractor tutorial.

函数和上下文级别的设置

除了全局级别设置,我们还可以在函数级别或上下文管理器级别设置后端、dtype 和contractor:

with tc.runtime_backend("tensorflow"):
    with tc.runtime_dtype("complex128"):
        m = tc.backend.eye(2)
n = tc.backend.eye(2)
print(m, n) # m is tf tensor while n is numpy array

@tc.set_function_backend("tensorflow")
@tc.set_function_dtype("complex128")
def f():
    return tc.backend.eye(2)
print(f()) # complex128 tf tensor

噪声电路模拟#

蒙特卡洛态模拟器

对于蒙特卡洛轨迹噪声模拟器,可以轻松处理幺正的 Kraus 通道。 不过,TensorCircuit 还支持完全可即时编译和可微分的通用 Kraus 通道蒙特卡罗模拟。

def noisecircuit(random):
    c = tc.Circuit(1)
    c.x(0)
    c.thermalrelaxation(
        0,
        t1=300,
        t2=400,
        time=1000,
        method="ByChoi",
        excitedstatepopulation=0,
        status=random,
    )
    return c.expectation_ps(z=[0])


K = tc.set_backend("tensorflow")
noisec_vmap = K.jit(K.vmap(noisecircuit, vectorized_argnums=0))
nmc = 10000
random = K.implicit_randu(nmc)
valuemc = K.mean(K.numpy(noisec_vmap(random)))
# (0.931+0j)

密度矩阵模拟器

密度矩阵模拟器``tc.DMCircuit`` 以完整形式模拟噪声,但需要两倍的量子比特。API 与 tc.Circuit 基本相同。

def noisecircuitdm():
    dmc = tc.DMCircuit(1)
    dmc.x(0)
    dmc.thermalrelaxation(
        0, t1=300, t2=400, time=1000, method="ByChoi", excitedstatepopulation=0
    )
    return dmc.expectation_ps(z=[0])


K = tc.set_backend("tensorflow")
noisec_jit = K.jit(noisecircuitdm)
valuedm = noisec_jit()
# (0.931+0j)

Experiment with quantum errors:

Multiple quantum errors can be added on circuit.

c = tc.Circuit(1)
c.x(0)
c.thermalrelaxation(
    0, t1=300, t2=400, time=1000, method="ByChoi", excitedstatepopulation=0
)
c.generaldepolarizing(0, p=0.01, num_qubits=1)
c.phasedamping(0, gamma=0.2)
c.amplitudedamping(0, gamma=0.25, p=0.2)
c.reset(0)
c.expectation_ps(z=[0])

Experiment with readout error:

Readout error can be added in experiments for sampling and expectation value calculation.

c = tc.Circuit(3)
c.X(0)
readout_error = []
readout_error.append([0.9, 0.75])  # readout error of qubit 0   p0|0=0.9, p1|1=0.75
readout_error.append([0.4, 0.7])  # readout error of qubit 1
readout_error.append([0.7, 0.9])  # readout error of qubit 2
value = c.sample_expectation_ps(z=[0, 1, 2], readout_error=readout_error)
# tf.Tensor(0.039999977, shape=(), dtype=float32)
instances = c.sample(
    batch=3,
    allow_state=True,
    readout_error=readout_error,
    random_generator=tc.backend.get_random_state(42),
    format_="sample_bin"
)
# tf.Tensor(
# [[1 0 0]
# [1 0 0]
# [1 0 1]], shape=(3, 3), dtype=int32)

矩阵乘积状态和矩阵乘积算子#

TensorCircuit 有自己的 MPS 和 MPO 类,起初在 TensorNetwork 中定义为“tc.QuVector” 和 “tc.QuOperator”。

作为``c.quvector()`` 的输出状态(未收缩)的张量网络形式,tc.QuVector 可以从``tc.Circuit`` 中提取。

QuVector 形成一个波函数 w,它也可以作为 c=tc.Circuit(n, mps_inputs=w) 的输入状态输入到 Circuit 中。

  • MPS 作为电路的输入状态

输入状态的 MPS/QuVector 表示具有更高效和紧凑的形式。

n = 3
nodes = [tc.gates.Gate(np.array([0.0, 1.0])) for _ in range(n)]
mps = tc.quantum.QuVector([nd[0] for nd in nodes])
c = tc.Circuit(n, mps_inputs=mps)
c.x(0)
c.expectation_ps(z=[0])
# 1.0
  • MPS 作为电路的(未计算的)输出状态

例如,在不显式计算状态幅度的情况下,计算波函数重叠的快速方法如下:

>>> c = tc.Circuit(3)
>>> [c.H(i) for i in range(3)]
[None, None, None]
>>> c.cnot(0, 1)
>>> c2 = tc.Circuit(3)
>>> [c2.H(i) for i in range(3)]
[None, None, None]
>>> c2.cnot(1, 0)
>>> q = c.quvector()
>>> q2 = c2.quvector().adjoint()
>>> (q2@q).eval_matrix()
array([[0.9999998+0.j]], dtype=complex64)
  • MPO 作为电路上的门

代替矩阵/节点格式的普通量子门,我们可以直接应用 MPO/QuOperator 格式的门。

>>> x0, x1 = tc.gates.x(), tc.gates.x()
>>> mpo = tc.quantum.QuOperator([x0[0], x1[0]], [x0[1], x1[1]])
>>> c = tc.Circuit(2)
>>> c.mpo(0, 1, mpo=mpo)
>>> c.state()
array([0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j], dtype=complex64)

以 MPO 格式定义的代表门是 multicontrol 门。

  • MPO作为电路期望估测算子

我们还可以测量运算符对 MPO/QuOperator 格式的电路输出状态的期望。

>>> z0, z1 = tc.gates.z(), tc.gates.z()
>>> mpo = tc.quantum.QuOperator([z0[0], z1[0]], [z0[1], z1[1]])
>>> c = tc.Circuit(2)
>>> c.X(0)
>>> tc.templates.measurements.mpo_expectation(c, mpo)
-1.0

接口#

与 PyTorch 模块混合的 PyTorch 接口:

正如我们在后端部分提到的,PyTorch 后端可能缺少高级功能。 这并不意味着我们不能将高级量子电路模块与 PyTorch 神经模块混合。 我们可以在 TensorFlow 或 Jax 后端运行量子函数,同时使用 Torch 接口包装它。

import tensorcircuit as tc
from tensorcircuit.interfaces import torch_interface
import torch

tc.set_backend("tensorflow")


def f(params):
    c = tc.Circuit(1)
    c.rx(0, theta=params[0])
    c.ry(0, theta=params[1])
    return c.expectation([tc.gates.z(), [0]])


f_torch = torch_interface(f, jit=True)

a = torch.ones([2], requires_grad=True)
b = f_torch(a)
c = b ** 2
c.backward()

print(a.grad)

For a GPU/CPU, torch/tensorflow, quantum/classical hybrid machine learning pipeline enabled by tensorcircuit, see example script.

There is also a more flexible torch interface that support static non-tensor inputs as keyword arguments, which can be utilized as below:

def f(a, i):
    s = 0.
    for _ in range(i):
        s += a
    return s

f_torch = tc.interfaces.torch_interface_kws(f)
f_torch(torch.ones([2]), i=3)

We also provider wrapper of quantum function for torch module as tensorcircuit.TorchLayer() alias to tensorcircuit.torchnn.QuantumNet().

For TorchLayer, use_interface=True is by default, which natively allow the quantum function defined on other tensorcircuit backends, such as jax or tf for speed consideration.

TorchLayer can process multiple input arguments as multiple function inputs, following torch practice.

n = 3
p = 0.1
K = tc.backend
torchb = tc.get_backend("pytorch")

def f(state, noise, weights):
    c = tc.Circuit(n, inputs=state)
    for i in range(n):
        c.rz(i, theta=weights[i])
    for i in range(n):
        c.depolarizing(i, px=p, py=p, pz=p, status=noise[i])
    return K.real(c.expectation_ps(x=[0]))

layer = tc.TorchLayer(f, [n], use_vmap=True, vectorized_argnums=[0, 1])
state = torchb.ones([2, 2**n]) / 2 ** (n / 2)
noise = 0.2 * torchb.ones([2, n], dtype="float32")
l = layer(state,noise)
lsum = torchb.sum(l)
print(l)
lsum.backward()
for p in layer.parameters():
    print(p.grad)

TensorFlow interfaces:

Similar rules apply similar as torch interface. The interface can even be used within jit environment outside. See tensorcircuit.interfaces.tensorflow.tensorflow_interface().

We also provider enable_dlpack=True option in torch and tf interfaces, which allow the tensor transformation happen without memory transfer via dlpack, higher version of tf or torch package required.

We also provider wrapper of quantum function for keras layer as tensorcircuit.KerasLayer() alias to tensorcircuit.keras.KerasLayer().

KerasLayer can process multiple input arguments with the input as a dict, following the common keras practice, see example below.

def f(inputs, weights):
    state = inputs["state"]
    noise = inputs["noise"]
    c = tc.Circuit(n, inputs=state)
    for i in range(n):
        c.rz(i, theta=weights[i])
    for i in range(n):
        c.depolarizing(i, px=p, py=p, pz=p, status=noise[i])
    return K.real(c.expectation_ps(x=[0]))

layer = tc.KerasLayer(f, [n])
v = {"state": K.ones([1, 2**n]) / 2 ** (n / 2), "noise": 0.2 * K.ones([1, n])}
with tf.GradientTape() as tape:
    l = layer(v)
grad = tape.gradient(l, layer.trainable_variables)

使用 scipy接口使用scipy优化器:

为带有 jac=True 的 scipy 接口自动将量子函数转换为与 scipy 兼容的 value 和 grad 函数。

n = 3

def f(param):
    c = tc.Circuit(n)
    for i in range(n):
        c.rx(i, theta=param[0, i])
        c.rz(i, theta=param[1, i])
    loss = c.expectation(
        [
            tc.gates.y(),
            [
                0,
            ],
        ]
    )
    return tc.backend.real(loss)

f_scipy = tc.interfaces.scipy_optimize_interface(f, shape=[2, n])
r = optimize.minimize(f_scipy, np.zeros([2 * n]), method="L-BFGS-B", jac=True)

捷径模板#

测量

  • 在一般图上定义的伊辛型哈密顿量

参考 tensorcircuit.templates.measurements.spin_glass_measurements()

  • 具有可能存在的外场的一般图上的海森堡哈密顿量

参考 tensorcircuit.templates.measurements.heisenberg_measurements()

电路块

c = tc.Circuit(4)
c = tc.templates.blocks.example_block(c, tc.backend.ones([16]))
_images/example_block.png
c = tc.Circuit(4)
c = tc.templates.blocks.Bell_pair_block(c)
_images/bell_pair_block.png