pub struct MatrixProductState { /* private fields */ }
Expand description
Matrix Product State representation of a circuit
Implementations§
Source§impl MatrixProductState
impl MatrixProductState
Sourcepub fn from_circuit<const N: usize>(
circuit: &Circuit<N>,
) -> QuantRS2Result<Self>
pub fn from_circuit<const N: usize>( circuit: &Circuit<N>, ) -> QuantRS2Result<Self>
Create MPS from circuit
Examples found in repository?
examples/tensor_network_demo.rs (line 134)
111fn demo_mps_representation() -> quantrs2_core::error::QuantRS2Result<()> {
112 println!("--- Matrix Product State Representation ---");
113
114 // Create a circuit that generates an interesting entangled state
115 let mut circuit = Circuit::<6>::new();
116
117 // Create W state: (|100000⟩ + |010000⟩ + |001000⟩ + |000100⟩ + |000010⟩ + |000001⟩)/√6
118 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 // Convert to MPS
134 let mps = MatrixProductState::from_circuit(&circuit)?;
135 println!("Converted to MPS representation");
136
137 // Compress with different bond dimensions
138 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 // In a real implementation, would calculate actual compression metrics
145 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 // Build a deep circuit
158 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 // Test different compression methods
173 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 // Try to decompress
191 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 // Create a circuit with specific structure
203 let mut circuit = Circuit::<4>::new();
204
205 // Layer 1: Single-qubit gates
206 for i in 0..4 {
207 circuit.add_gate(Hadamard { target: QubitId(i) })?;
208 }
209
210 // Layer 2: Entangling gates
211 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 // Layer 3: Cross entangling
221 circuit.add_gate(CNOT {
222 control: QubitId(1),
223 target: QubitId(2),
224 })?;
225
226 // Convert to tensor network
227 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 // Contract the network
237 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 // Create circuits to compare
248 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 // Convert to MPS for efficient comparison
271 let mps1 = MatrixProductState::from_circuit(&circuit1)?;
272 let mps2 = MatrixProductState::from_circuit(&circuit2)?;
273
274 // Calculate overlap (would indicate circuit similarity)
275 let overlap = mps1.overlap(&mps2)?;
276 println!("Circuit overlap: |⟨ψ₁|ψ₂⟩| = {:.6}", overlap.norm());
277
278 // Compress both circuits
279 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}
Sourcepub fn compress(
&mut self,
max_bond_dim: usize,
tolerance: f64,
) -> QuantRS2Result<()>
pub fn compress( &mut self, max_bond_dim: usize, tolerance: f64, ) -> QuantRS2Result<()>
Compress the MPS
Examples found in repository?
examples/tensor_network_demo.rs (line 142)
111fn demo_mps_representation() -> quantrs2_core::error::QuantRS2Result<()> {
112 println!("--- Matrix Product State Representation ---");
113
114 // Create a circuit that generates an interesting entangled state
115 let mut circuit = Circuit::<6>::new();
116
117 // Create W state: (|100000⟩ + |010000⟩ + |001000⟩ + |000100⟩ + |000010⟩ + |000001⟩)/√6
118 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 // Convert to MPS
134 let mps = MatrixProductState::from_circuit(&circuit)?;
135 println!("Converted to MPS representation");
136
137 // Compress with different bond dimensions
138 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 // In a real implementation, would calculate actual compression metrics
145 println!("Max bond dimension {}: compression successful", max_bond);
146 }
147
148 println!();
149 Ok(())
150}
Sourcepub fn overlap(
&self,
other: &MatrixProductState,
) -> QuantRS2Result<Complex<f64>>
pub fn overlap( &self, other: &MatrixProductState, ) -> QuantRS2Result<Complex<f64>>
Calculate overlap with another MPS
Examples found in repository?
examples/tensor_network_demo.rs (line 275)
244fn demo_circuit_analysis() -> quantrs2_core::error::QuantRS2Result<()> {
245 println!("--- Circuit Analysis via Tensor Networks ---");
246
247 // Create circuits to compare
248 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 // Convert to MPS for efficient comparison
271 let mps1 = MatrixProductState::from_circuit(&circuit1)?;
272 let mps2 = MatrixProductState::from_circuit(&circuit2)?;
273
274 // Calculate overlap (would indicate circuit similarity)
275 let overlap = mps1.overlap(&mps2)?;
276 println!("Circuit overlap: |⟨ψ₁|ψ₂⟩| = {:.6}", overlap.norm());
277
278 // Compress both circuits
279 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}
Sourcepub fn expectation_value(
&self,
observable: &TensorNetwork,
) -> QuantRS2Result<f64>
pub fn expectation_value( &self, observable: &TensorNetwork, ) -> QuantRS2Result<f64>
Calculate expectation value of observable
Trait Implementations§
Auto Trait Implementations§
impl Freeze for MatrixProductState
impl RefUnwindSafe for MatrixProductState
impl Send for MatrixProductState
impl Sync for MatrixProductState
impl Unpin for MatrixProductState
impl UnwindSafe for MatrixProductState
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
The inverse inclusion map: attempts to construct
self
from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
Checks if
self
is actually part of its subset T
(and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
Use with care! Same as
self.to_subset
but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
The inclusion map: converts
self
to the equivalent element of its superset.