tensor_network_demo/
tensor_network_demo.rs1use nalgebra::Complex;
7use quantrs2_circuit::prelude::*;
8use quantrs2_core::gate::multi::CNOT;
9use quantrs2_core::gate::single::{Hadamard, RotationZ, T};
10use quantrs2_core::qubit::QubitId;
11
12type C64 = Complex<f64>;
13
14fn main() -> quantrs2_core::error::QuantRS2Result<()> {
15 println!("=== Tensor Network Compression Demo ===\n");
16
17 demo_basic_tensor_network()?;
18 demo_circuit_compression()?;
19 demo_mps_representation()?;
20 demo_compression_methods()?;
21
22 Ok(())
23}
24
25fn demo_basic_tensor_network() -> quantrs2_core::error::QuantRS2Result<()> {
26 println!("--- Basic Tensor Network Construction ---");
27
28 let identity = Tensor::identity(2, "in".to_string(), "out".to_string());
30 println!(
31 "Created identity tensor: rank={}, size={}",
32 identity.rank(),
33 identity.size()
34 );
35
36 let h_data = vec![
38 C64::new(1.0 / 2.0_f64.sqrt(), 0.0),
39 C64::new(1.0 / 2.0_f64.sqrt(), 0.0),
40 C64::new(1.0 / 2.0_f64.sqrt(), 0.0),
41 C64::new(-1.0 / 2.0_f64.sqrt(), 0.0),
42 ];
43 let h_tensor = Tensor::new(
44 h_data,
45 vec![2, 2],
46 vec!["h_in".to_string(), "h_out".to_string()],
47 );
48
49 let mut tn = TensorNetwork::new();
51 let id_idx = tn.add_tensor(identity);
52 let h_idx = tn.add_tensor(h_tensor);
53
54 tn.add_bond(id_idx, "out".to_string(), h_idx, "h_in".to_string())?;
56
57 println!("Built tensor network with {} tensors and {} bonds", 2, 1);
58 println!();
59
60 Ok(())
61}
62
63fn demo_circuit_compression() -> quantrs2_core::error::QuantRS2Result<()> {
64 println!("--- Circuit Compression ---");
65
66 let mut circuit = Circuit::<4>::new();
68
69 for i in 0..3 {
71 circuit.add_gate(Hadamard { target: QubitId(i) })?;
72 }
73
74 for i in 0..3 {
75 circuit.add_gate(CNOT {
76 control: QubitId(i),
77 target: QubitId(i + 1),
78 })?;
79 }
80
81 for i in 0..4 {
82 circuit.add_gate(T { target: QubitId(i) })?;
83 }
84
85 for i in (1..4).rev() {
86 circuit.add_gate(CNOT {
87 control: QubitId(i - 1),
88 target: QubitId(i),
89 })?;
90 }
91
92 println!("Original circuit: {} gates", circuit.num_gates());
93
94 let compressor = TensorNetworkCompressor::new(16); let compressed = compressor.compress(&circuit)?;
97
98 println!(
99 "Compression ratio: {:.2}%",
100 compressed.compression_ratio() * 100.0
101 );
102
103 let fidelity = compressed.fidelity(&circuit)?;
105 println!("Fidelity with original: {:.6}", fidelity);
106
107 println!();
108 Ok(())
109}
110
111fn demo_mps_representation() -> quantrs2_core::error::QuantRS2Result<()> {
112 println!("--- Matrix Product State Representation ---");
113
114 let mut circuit = Circuit::<6>::new();
116
117 circuit.add_gate(Hadamard { target: QubitId(0) })?;
119 circuit.add_gate(RotationZ {
120 target: QubitId(0),
121 theta: std::f64::consts::PI / 3.0,
122 })?;
123
124 for i in 0..5 {
125 circuit.add_gate(CNOT {
126 control: QubitId(i),
127 target: QubitId(i + 1),
128 })?;
129 }
130
131 println!("Created circuit for W state preparation");
132
133 let mps = MatrixProductState::from_circuit(&circuit)?;
135 println!("Converted to MPS representation");
136
137 let bond_dims = vec![2, 4, 8, 16];
139
140 for &max_bond in &bond_dims {
141 let mut mps_copy = MatrixProductState::from_circuit(&circuit)?;
142 mps_copy.compress(max_bond, 1e-10)?;
143
144 println!("Max bond dimension {}: compression successful", max_bond);
146 }
147
148 println!();
149 Ok(())
150}
151
152fn demo_compression_methods() -> quantrs2_core::error::QuantRS2Result<()> {
153 println!("--- Different Compression Methods ---");
154
155 let mut circuit = Circuit::<5>::new();
156
157 for _ in 0..5 {
159 for i in 0..5 {
160 circuit.add_gate(Hadamard { target: QubitId(i) })?;
161 }
162 for i in 0..4 {
163 circuit.add_gate(CNOT {
164 control: QubitId(i),
165 target: QubitId(i + 1),
166 })?;
167 }
168 }
169
170 println!("Built deep circuit with {} gates", circuit.num_gates());
171
172 let methods = vec![
174 CompressionMethod::SVD,
175 CompressionMethod::DMRG,
176 CompressionMethod::TEBD,
177 ];
178
179 for method in methods {
180 let compressor = TensorNetworkCompressor::new(32).with_method(method.clone());
181
182 let compressed = compressor.compress(&circuit)?;
183
184 println!("\n{:?} compression:", method);
185 println!(
186 " Compression ratio: {:.2}%",
187 compressed.compression_ratio() * 100.0
188 );
189
190 let decompressed = compressed.decompress()?;
192 println!(" Decompressed to {} gates", decompressed.num_gates());
193 }
194
195 println!();
196 Ok(())
197}
198
199fn demo_tensor_contraction() -> quantrs2_core::error::QuantRS2Result<()> {
200 println!("--- Tensor Contraction Optimization ---");
201
202 let mut circuit = Circuit::<4>::new();
204
205 for i in 0..4 {
207 circuit.add_gate(Hadamard { target: QubitId(i) })?;
208 }
209
210 circuit.add_gate(CNOT {
212 control: QubitId(0),
213 target: QubitId(1),
214 })?;
215 circuit.add_gate(CNOT {
216 control: QubitId(2),
217 target: QubitId(3),
218 })?;
219
220 circuit.add_gate(CNOT {
222 control: QubitId(1),
223 target: QubitId(2),
224 })?;
225
226 let converter = CircuitToTensorNetwork::<4>::new()
228 .with_max_bond_dim(8)
229 .with_tolerance(1e-12);
230
231 let tn = converter.convert(&circuit)?;
232
233 println!("Converted circuit to tensor network");
234 println!("Network has {} tensors", circuit.num_gates());
235
236 let result = tn.contract_all()?;
238 println!("Contracted to single tensor of rank {}", result.rank());
239
240 println!();
241 Ok(())
242}
243
244fn demo_circuit_analysis() -> quantrs2_core::error::QuantRS2Result<()> {
245 println!("--- Circuit Analysis via Tensor Networks ---");
246
247 let mut circuit1 = Circuit::<3>::new();
249 circuit1.add_gate(Hadamard { target: QubitId(0) })?;
250 circuit1.add_gate(CNOT {
251 control: QubitId(0),
252 target: QubitId(1),
253 })?;
254 circuit1.add_gate(CNOT {
255 control: QubitId(1),
256 target: QubitId(2),
257 })?;
258
259 let mut circuit2 = Circuit::<3>::new();
260 circuit2.add_gate(Hadamard { target: QubitId(0) })?;
261 circuit2.add_gate(CNOT {
262 control: QubitId(0),
263 target: QubitId(2),
264 })?;
265 circuit2.add_gate(CNOT {
266 control: QubitId(0),
267 target: QubitId(1),
268 })?;
269
270 let mps1 = MatrixProductState::from_circuit(&circuit1)?;
272 let mps2 = MatrixProductState::from_circuit(&circuit2)?;
273
274 let overlap = mps1.overlap(&mps2)?;
276 println!("Circuit overlap: |⟨ψ₁|ψ₂⟩| = {:.6}", overlap.norm());
277
278 let compressor = TensorNetworkCompressor::new(16);
280 let comp1 = compressor.compress(&circuit1)?;
281 let comp2 = compressor.compress(&circuit2)?;
282
283 println!(
284 "Circuit 1 compression: {:.2}%",
285 comp1.compression_ratio() * 100.0
286 );
287 println!(
288 "Circuit 2 compression: {:.2}%",
289 comp2.compression_ratio() * 100.0
290 );
291
292 Ok(())
293}
294
295#[cfg(test)]
296mod tests {
297 use super::*;
298
299 #[test]
300 fn test_tensor_network_demo() {
301 assert!(main().is_ok());
302 }
303}