pub struct QuantumBoltzmannMachine { /* private fields */ }Expand description
Quantum Boltzmann Machine
Implementations§
Source§impl QuantumBoltzmannMachine
impl QuantumBoltzmannMachine
Sourcepub fn new(
num_visible: usize,
num_hidden: usize,
temperature: f64,
learning_rate: f64,
) -> Result<Self>
pub fn new( num_visible: usize, num_hidden: usize, temperature: f64, learning_rate: f64, ) -> Result<Self>
Create a new Quantum Boltzmann Machine
Examples found in repository?
examples/quantum_boltzmann.rs (lines 49-54)
47fn basic_qbm_demo() -> Result<()> {
48 // Create a small QBM
49 let mut qbm = QuantumBoltzmannMachine::new(
50 4, // visible units
51 2, // hidden units
52 1.0, // temperature
53 0.01, // learning rate
54 )?;
55
56 println!(" Created QBM with 4 visible and 2 hidden units");
57
58 // Generate synthetic binary data
59 let data = generate_binary_patterns(100, 4);
60
61 // Train the QBM
62 println!(" Training on binary patterns...");
63 let losses = qbm.train(&data, 50, 10)?;
64
65 println!(" Training complete:");
66 println!(" - Initial loss: {:.4}", losses[0]);
67 println!(" - Final loss: {:.4}", losses.last().unwrap());
68
69 // Sample from trained model
70 let samples = qbm.sample(5)?;
71 println!("\n Generated samples:");
72 for (i, sample) in samples.outer_iter().enumerate() {
73 print!(" Sample {}: [", i + 1);
74 for val in sample {
75 print!("{val:.0} ");
76 }
77 println!("]");
78 }
79
80 Ok(())
81}
82
83/// RBM demonstration with persistent contrastive divergence
84fn rbm_demo() -> Result<()> {
85 // Create RBM with annealing
86 let annealing = AnnealingSchedule::new(2.0, 0.5, 100);
87
88 let mut rbm = QuantumRBM::new(
89 6, // visible units
90 3, // hidden units
91 2.0, // initial temperature
92 0.01, // learning rate
93 )?
94 .with_annealing(annealing);
95
96 println!(" Created Quantum RBM with annealing schedule");
97
98 // Generate correlated binary data
99 let data = generate_correlated_data(200, 6);
100
101 // Train with PCD
102 println!(" Training with Persistent Contrastive Divergence...");
103 let losses = rbm.train_pcd(
104 &data, 100, // epochs
105 20, // batch size
106 50, // persistent chains
107 )?;
108
109 // Analyze training
110 let improvement = (losses[0] - losses.last().unwrap()) / losses[0] * 100.0;
111 println!(" Training statistics:");
112 println!(" - Loss reduction: {improvement:.1}%");
113 println!(" - Final temperature: 0.5");
114
115 // Test reconstruction
116 let test_data = data.slice(s![0..5, ..]).to_owned();
117 let reconstructed = rbm.qbm().reconstruct(&test_data)?;
118
119 println!("\n Reconstruction quality:");
120 for i in 0..3 {
121 print!(" Original: [");
122 for val in test_data.row(i) {
123 print!("{val:.0} ");
124 }
125 print!("] → Reconstructed: [");
126 for val in reconstructed.row(i) {
127 print!("{val:.0} ");
128 }
129 println!("]");
130 }
131
132 Ok(())
133}
134
135/// Deep Boltzmann Machine demonstration
136fn deep_boltzmann_demo() -> Result<()> {
137 // Create a 3-layer DBM
138 let layer_sizes = vec![8, 4, 2];
139 let mut dbm = DeepBoltzmannMachine::new(
140 layer_sizes.clone(),
141 1.0, // temperature
142 0.01, // learning rate
143 )?;
144
145 println!(" Created Deep Boltzmann Machine:");
146 println!(" - Architecture: {layer_sizes:?}");
147 println!(" - Total layers: {}", dbm.rbms().len());
148
149 // Generate hierarchical data
150 let data = generate_hierarchical_data(300, 8);
151
152 // Layer-wise pretraining
153 println!("\n Performing layer-wise pretraining...");
154 dbm.pretrain(
155 &data, 50, // epochs per layer
156 30, // batch size
157 )?;
158
159 println!("\n Pretraining complete!");
160 println!(" Each layer learned increasingly abstract features");
161
162 Ok(())
163}
164
165/// Energy landscape visualization
166fn energy_landscape_demo() -> Result<()> {
167 // Create small QBM for visualization
168 let qbm = QuantumBoltzmannMachine::new(
169 2, // visible units (for 2D visualization)
170 1, // hidden unit
171 0.5, // temperature
172 0.01, // learning rate
173 )?;
174
175 println!(" Analyzing energy landscape of 2-unit system");
176
177 // Compute energy for all 4 possible states
178 let states = [
179 Array1::from_vec(vec![0.0, 0.0]),
180 Array1::from_vec(vec![0.0, 1.0]),
181 Array1::from_vec(vec![1.0, 0.0]),
182 Array1::from_vec(vec![1.0, 1.0]),
183 ];
184
185 println!("\n State energies:");
186 for (i, state) in states.iter().enumerate() {
187 let energy = qbm.energy(state);
188 let prob = (-energy / qbm.temperature()).exp();
189 println!(
190 " State [{:.0}, {:.0}]: E = {:.3}, P ∝ {:.3}",
191 state[0], state[1], energy, prob
192 );
193 }
194
195 // Show coupling matrix
196 println!("\n Coupling matrix:");
197 for i in 0..3 {
198 print!(" [");
199 for j in 0..3 {
200 print!("{:6.3} ", qbm.couplings()[[i, j]]);
201 }
202 println!("]");
203 }
204
205 Ok(())
206}Sourcepub fn energy(&self, state: &Array1<f64>) -> f64
pub fn energy(&self, state: &Array1<f64>) -> f64
Compute energy of a configuration
Examples found in repository?
examples/quantum_boltzmann.rs (line 187)
166fn energy_landscape_demo() -> Result<()> {
167 // Create small QBM for visualization
168 let qbm = QuantumBoltzmannMachine::new(
169 2, // visible units (for 2D visualization)
170 1, // hidden unit
171 0.5, // temperature
172 0.01, // learning rate
173 )?;
174
175 println!(" Analyzing energy landscape of 2-unit system");
176
177 // Compute energy for all 4 possible states
178 let states = [
179 Array1::from_vec(vec![0.0, 0.0]),
180 Array1::from_vec(vec![0.0, 1.0]),
181 Array1::from_vec(vec![1.0, 0.0]),
182 Array1::from_vec(vec![1.0, 1.0]),
183 ];
184
185 println!("\n State energies:");
186 for (i, state) in states.iter().enumerate() {
187 let energy = qbm.energy(state);
188 let prob = (-energy / qbm.temperature()).exp();
189 println!(
190 " State [{:.0}, {:.0}]: E = {:.3}, P ∝ {:.3}",
191 state[0], state[1], energy, prob
192 );
193 }
194
195 // Show coupling matrix
196 println!("\n Coupling matrix:");
197 for i in 0..3 {
198 print!(" [");
199 for j in 0..3 {
200 print!("{:6.3} ", qbm.couplings()[[i, j]]);
201 }
202 println!("]");
203 }
204
205 Ok(())
206}Sourcepub fn create_gibbs_circuit(&self) -> Result<()>
pub fn create_gibbs_circuit(&self) -> Result<()>
Create quantum circuit for Gibbs state preparation
Sourcepub fn sample(&self, num_samples: usize) -> Result<Array2<f64>>
pub fn sample(&self, num_samples: usize) -> Result<Array2<f64>>
Sample from the Boltzmann distribution
Examples found in repository?
examples/quantum_boltzmann.rs (line 70)
47fn basic_qbm_demo() -> Result<()> {
48 // Create a small QBM
49 let mut qbm = QuantumBoltzmannMachine::new(
50 4, // visible units
51 2, // hidden units
52 1.0, // temperature
53 0.01, // learning rate
54 )?;
55
56 println!(" Created QBM with 4 visible and 2 hidden units");
57
58 // Generate synthetic binary data
59 let data = generate_binary_patterns(100, 4);
60
61 // Train the QBM
62 println!(" Training on binary patterns...");
63 let losses = qbm.train(&data, 50, 10)?;
64
65 println!(" Training complete:");
66 println!(" - Initial loss: {:.4}", losses[0]);
67 println!(" - Final loss: {:.4}", losses.last().unwrap());
68
69 // Sample from trained model
70 let samples = qbm.sample(5)?;
71 println!("\n Generated samples:");
72 for (i, sample) in samples.outer_iter().enumerate() {
73 print!(" Sample {}: [", i + 1);
74 for val in sample {
75 print!("{val:.0} ");
76 }
77 println!("]");
78 }
79
80 Ok(())
81}Sourcepub fn compute_gradients(
&self,
data: &Array2<f64>,
) -> Result<(Array2<f64>, Array1<f64>)>
pub fn compute_gradients( &self, data: &Array2<f64>, ) -> Result<(Array2<f64>, Array1<f64>)>
Compute gradients using contrastive divergence
Sourcepub fn train(
&mut self,
data: &Array2<f64>,
epochs: usize,
batch_size: usize,
) -> Result<Vec<f64>>
pub fn train( &mut self, data: &Array2<f64>, epochs: usize, batch_size: usize, ) -> Result<Vec<f64>>
Train the Boltzmann machine
Examples found in repository?
examples/quantum_boltzmann.rs (line 63)
47fn basic_qbm_demo() -> Result<()> {
48 // Create a small QBM
49 let mut qbm = QuantumBoltzmannMachine::new(
50 4, // visible units
51 2, // hidden units
52 1.0, // temperature
53 0.01, // learning rate
54 )?;
55
56 println!(" Created QBM with 4 visible and 2 hidden units");
57
58 // Generate synthetic binary data
59 let data = generate_binary_patterns(100, 4);
60
61 // Train the QBM
62 println!(" Training on binary patterns...");
63 let losses = qbm.train(&data, 50, 10)?;
64
65 println!(" Training complete:");
66 println!(" - Initial loss: {:.4}", losses[0]);
67 println!(" - Final loss: {:.4}", losses.last().unwrap());
68
69 // Sample from trained model
70 let samples = qbm.sample(5)?;
71 println!("\n Generated samples:");
72 for (i, sample) in samples.outer_iter().enumerate() {
73 print!(" Sample {}: [", i + 1);
74 for val in sample {
75 print!("{val:.0} ");
76 }
77 println!("]");
78 }
79
80 Ok(())
81}Sourcepub fn reconstruct(&self, visible: &Array2<f64>) -> Result<Array2<f64>>
pub fn reconstruct(&self, visible: &Array2<f64>) -> Result<Array2<f64>>
Reconstruct visible units
Examples found in repository?
examples/quantum_boltzmann.rs (line 117)
84fn rbm_demo() -> Result<()> {
85 // Create RBM with annealing
86 let annealing = AnnealingSchedule::new(2.0, 0.5, 100);
87
88 let mut rbm = QuantumRBM::new(
89 6, // visible units
90 3, // hidden units
91 2.0, // initial temperature
92 0.01, // learning rate
93 )?
94 .with_annealing(annealing);
95
96 println!(" Created Quantum RBM with annealing schedule");
97
98 // Generate correlated binary data
99 let data = generate_correlated_data(200, 6);
100
101 // Train with PCD
102 println!(" Training with Persistent Contrastive Divergence...");
103 let losses = rbm.train_pcd(
104 &data, 100, // epochs
105 20, // batch size
106 50, // persistent chains
107 )?;
108
109 // Analyze training
110 let improvement = (losses[0] - losses.last().unwrap()) / losses[0] * 100.0;
111 println!(" Training statistics:");
112 println!(" - Loss reduction: {improvement:.1}%");
113 println!(" - Final temperature: 0.5");
114
115 // Test reconstruction
116 let test_data = data.slice(s![0..5, ..]).to_owned();
117 let reconstructed = rbm.qbm().reconstruct(&test_data)?;
118
119 println!("\n Reconstruction quality:");
120 for i in 0..3 {
121 print!(" Original: [");
122 for val in test_data.row(i) {
123 print!("{val:.0} ");
124 }
125 print!("] → Reconstructed: [");
126 for val in reconstructed.row(i) {
127 print!("{val:.0} ");
128 }
129 println!("]");
130 }
131
132 Ok(())
133}Sourcepub fn temperature(&self) -> f64
pub fn temperature(&self) -> f64
Get temperature
Examples found in repository?
examples/quantum_boltzmann.rs (line 188)
166fn energy_landscape_demo() -> Result<()> {
167 // Create small QBM for visualization
168 let qbm = QuantumBoltzmannMachine::new(
169 2, // visible units (for 2D visualization)
170 1, // hidden unit
171 0.5, // temperature
172 0.01, // learning rate
173 )?;
174
175 println!(" Analyzing energy landscape of 2-unit system");
176
177 // Compute energy for all 4 possible states
178 let states = [
179 Array1::from_vec(vec![0.0, 0.0]),
180 Array1::from_vec(vec![0.0, 1.0]),
181 Array1::from_vec(vec![1.0, 0.0]),
182 Array1::from_vec(vec![1.0, 1.0]),
183 ];
184
185 println!("\n State energies:");
186 for (i, state) in states.iter().enumerate() {
187 let energy = qbm.energy(state);
188 let prob = (-energy / qbm.temperature()).exp();
189 println!(
190 " State [{:.0}, {:.0}]: E = {:.3}, P ∝ {:.3}",
191 state[0], state[1], energy, prob
192 );
193 }
194
195 // Show coupling matrix
196 println!("\n Coupling matrix:");
197 for i in 0..3 {
198 print!(" [");
199 for j in 0..3 {
200 print!("{:6.3} ", qbm.couplings()[[i, j]]);
201 }
202 println!("]");
203 }
204
205 Ok(())
206}Sourcepub fn couplings(&self) -> &Array2<f64>
pub fn couplings(&self) -> &Array2<f64>
Get couplings matrix
Examples found in repository?
examples/quantum_boltzmann.rs (line 200)
166fn energy_landscape_demo() -> Result<()> {
167 // Create small QBM for visualization
168 let qbm = QuantumBoltzmannMachine::new(
169 2, // visible units (for 2D visualization)
170 1, // hidden unit
171 0.5, // temperature
172 0.01, // learning rate
173 )?;
174
175 println!(" Analyzing energy landscape of 2-unit system");
176
177 // Compute energy for all 4 possible states
178 let states = [
179 Array1::from_vec(vec![0.0, 0.0]),
180 Array1::from_vec(vec![0.0, 1.0]),
181 Array1::from_vec(vec![1.0, 0.0]),
182 Array1::from_vec(vec![1.0, 1.0]),
183 ];
184
185 println!("\n State energies:");
186 for (i, state) in states.iter().enumerate() {
187 let energy = qbm.energy(state);
188 let prob = (-energy / qbm.temperature()).exp();
189 println!(
190 " State [{:.0}, {:.0}]: E = {:.3}, P ∝ {:.3}",
191 state[0], state[1], energy, prob
192 );
193 }
194
195 // Show coupling matrix
196 println!("\n Coupling matrix:");
197 for i in 0..3 {
198 print!(" [");
199 for j in 0..3 {
200 print!("{:6.3} ", qbm.couplings()[[i, j]]);
201 }
202 println!("]");
203 }
204
205 Ok(())
206}Auto Trait Implementations§
impl Freeze for QuantumBoltzmannMachine
impl RefUnwindSafe for QuantumBoltzmannMachine
impl Send for QuantumBoltzmannMachine
impl Sync for QuantumBoltzmannMachine
impl Unpin for QuantumBoltzmannMachine
impl UnsafeUnpin for QuantumBoltzmannMachine
impl UnwindSafe for QuantumBoltzmannMachine
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.