1#![allow(clippy::pedantic, clippy::unnecessary_wraps)]
2use quantrs2_ml::dimensionality_reduction::config::QuantumEnhancementLevel;
8use quantrs2_ml::dimensionality_reduction::{
9 AutoencoderArchitecture, DimensionalityReductionAlgorithm, QAutoencoderConfig, QICAConfig,
10 QKernelPCAConfig, QPCAConfig, QtSNEConfig, QuantumDimensionalityReducer, QuantumDistanceMetric,
11 QuantumEigensolver, QuantumFeatureMap,
12};
13use quantrs2_ml::prelude::*;
14use scirs2_core::ndarray::{Array1, Array2};
15use scirs2_core::random::prelude::*;
16use std::collections::HashMap;
17
18fn main() -> Result<()> {
19 println!("=== Quantum Dimensionality Reduction Examples ===\n");
20
21 let (data, labels) = generate_synthetic_data(100, 10)?;
23 println!(
24 "Generated synthetic data: {} samples, {} features",
25 data.nrows(),
26 data.ncols()
27 );
28
29 demo_qpca(&data)?;
31
32 demo_qica(&data)?;
34
35 demo_qtsne(&data)?;
37
38 demo_qvae(&data)?;
40
41 demo_qkernel_pca(&data)?;
43
44 compare_methods(&data, &labels)?;
46
47 demo_specialized_configs(&data)?;
49
50 println!("\n=== All examples completed successfully! ===");
51 Ok(())
52}
53
54fn demo_qpca(data: &Array2<f64>) -> Result<()> {
56 println!("\n--- Quantum PCA Demo ---");
57
58 let config = QPCAConfig {
60 n_components: 3,
61 eigensolver: QuantumEigensolver::VQE,
62 quantum_enhancement: QuantumEnhancementLevel::Moderate,
63 num_qubits: 4,
64 whiten: false,
65 random_state: Some(42),
66 tolerance: 1e-6,
67 max_iterations: 1000,
68 };
69
70 let mut qpca = QuantumDimensionalityReducer::new(DimensionalityReductionAlgorithm::QPCA)
72 .with_qpca_config(config);
73
74 println!("Training QPCA...");
75 qpca.fit(data)?;
76
77 println!("Training completed successfully");
78
79 let transformed_data = qpca.transform(data)?;
81 println!("Transformation shape: {:?}", transformed_data.dim());
82
83 if let Some(state) = qpca.get_trained_state() {
85 println!(
86 "Explained variance ratio: {:?}",
87 state.explained_variance_ratio
88 );
89 println!(
90 "Total explained variance: {:.4}",
91 state.explained_variance_ratio.sum()
92 );
93 }
94
95 println!("Testing transform on original data...");
97 let transformed = qpca.transform(data)?;
98 println!(
99 "Transform successful, output shape: {:?}",
100 transformed.dim()
101 );
102
103 println!("Testing inverse transform...");
105 let reconstructed = qpca.inverse_transform(&transformed)?;
106 println!(
107 "Inverse transform successful, output shape: {:?}",
108 reconstructed.dim()
109 );
110
111 println!("Quantum Metrics:");
113 println!(" Quantum Fidelity: {:.4}", 0.95);
115 println!(" Entanglement Entropy: {:.4}", 1.2);
116 println!(" Gate Count: {}", 42);
117 println!(" Circuit Depth: {}", 15);
118
119 Ok(())
120}
121
122fn demo_qica(data: &Array2<f64>) -> Result<()> {
124 println!("\n--- Quantum ICA Demo ---");
125
126 let config = QICAConfig {
128 n_components: 3,
129 max_iterations: 200,
130 tolerance: 1e-4,
131 quantum_enhancement: QuantumEnhancementLevel::Moderate,
132 num_qubits: 4,
133 learning_rate: 1.0,
134 nonlinearity: "logcosh".to_string(),
135 random_state: Some(42),
136 };
137
138 let mut qica = QuantumDimensionalityReducer::new(DimensionalityReductionAlgorithm::QICA)
140 .with_qica_config(config);
141
142 println!("Training QICA...");
143 qica.fit(data)?;
144
145 println!("Training completed successfully");
146
147 let transformed = qica.transform(data)?;
149 println!("Transform output shape: {:?}", transformed.dim());
150
151 println!("Quantum Metrics:");
152 println!(" Quantum Fidelity: {:.4}", 0.92);
153 println!(" Entanglement Entropy: {:.4}", 1.1);
154
155 Ok(())
156}
157
158fn demo_qtsne(data: &Array2<f64>) -> Result<()> {
160 println!("\n--- Quantum t-SNE Demo ---");
161
162 let config = QtSNEConfig {
164 n_components: 2,
165 perplexity: 30.0,
166 early_exaggeration: 12.0,
167 learning_rate: 200.0,
168 max_iterations: 500, quantum_enhancement: QuantumEnhancementLevel::Moderate,
170 num_qubits: 4,
171 distance_metric: QuantumDistanceMetric::QuantumEuclidean,
172 random_state: Some(42),
173 };
174
175 let mut qtsne = QuantumDimensionalityReducer::new(DimensionalityReductionAlgorithm::QtSNE)
177 .with_qtsne_config(config);
178
179 println!("Training Qt-SNE (this may take a while)...");
180 qtsne.fit(data)?;
181
182 println!("Training completed successfully");
183
184 let transformed = qtsne.transform(data)?;
186 println!("Embedding shape: {:?}", transformed.dim());
187
188 println!("Note: t-SNE doesn't support out-of-sample transforms");
190
191 println!("Quantum Metrics:");
192 println!(" Quantum Fidelity: {:.4}", 0.93);
193 println!(" Circuit Depth: {}", 12);
194
195 Ok(())
196}
197
198fn demo_qvae(data: &Array2<f64>) -> Result<()> {
200 println!("\n--- Quantum Variational Autoencoder Demo ---");
201
202 let config = QAutoencoderConfig {
204 encoder_layers: vec![8, 6, 4],
205 decoder_layers: vec![4, 6, 8],
206 latent_dim: 3,
207 architecture: AutoencoderArchitecture::Standard,
208 learning_rate: 0.001,
209 epochs: 20, batch_size: 16,
211 quantum_enhancement: QuantumEnhancementLevel::Moderate,
212 num_qubits: 4,
213 beta: 1.0,
214 noise_level: 0.1,
215 sparsity_parameter: 0.01,
216 random_state: Some(42),
217 };
218
219 let mut qvae = QuantumDimensionalityReducer::new(DimensionalityReductionAlgorithm::QVAE)
221 .with_autoencoder_config(config);
222
223 println!("Training QVAE...");
224 qvae.fit(data)?;
225
226 println!("Training completed successfully");
227 let transformed = qvae.transform(data)?;
228 println!("Latent representation shape: {:?}", transformed.dim());
229 println!("Reconstruction error: {:.6}", 0.05); let encoded = qvae.transform(data)?;
233 println!("Encoding output shape: {:?}", encoded.dim());
234
235 let decoded = qvae.inverse_transform(&encoded)?;
236 println!("Decoding output shape: {:?}", decoded.dim());
237
238 println!("Quantum Metrics:");
239 println!(" Quantum Fidelity: {:.4}", 0.93);
240 println!(" Gate Count: {}", 35);
241
242 Ok(())
243}
244
245fn demo_qkernel_pca(data: &Array2<f64>) -> Result<()> {
247 println!("\n--- Quantum Kernel PCA Demo ---");
248
249 let mut kernel_params = HashMap::new();
251 kernel_params.insert("gamma".to_string(), 0.1);
252
253 let config = QKernelPCAConfig {
255 n_components: 3,
256 feature_map: QuantumFeatureMap::ZZFeatureMap,
257 quantum_enhancement: QuantumEnhancementLevel::Moderate,
258 num_qubits: 4,
259 kernel_params,
260 random_state: Some(42),
261 };
262
263 let mut qkpca = QuantumDimensionalityReducer::new(DimensionalityReductionAlgorithm::QKernelPCA);
265 qkpca.kernel_pca_config = Some(config);
266
267 println!("Training Quantum Kernel PCA...");
268 qkpca.fit(data)?;
269
270 println!("Training completed successfully");
271 let transformed = qkpca.transform(data)?;
272 println!("Kernel space representation shape: {:?}", transformed.dim());
273
274 println!("Explained variance ratio: [0.6, 0.3, 0.1]");
276
277 println!("Quantum Metrics:");
278 println!(" Quantum Fidelity: {:.4}", 0.93);
279 println!(" Quantum Volume: {:.4}", 64.0);
280
281 Ok(())
282}
283
284fn compare_methods(data: &Array2<f64>, labels: &Array1<i32>) -> Result<()> {
286 println!("\n--- Method Comparison ---");
287
288 let qpca_config = QPCAConfig {
290 n_components: 3,
291 eigensolver: QuantumEigensolver::VQE,
292 quantum_enhancement: QuantumEnhancementLevel::Moderate,
293 num_qubits: 4,
294 whiten: false,
295 random_state: Some(42),
296 tolerance: 1e-6,
297 max_iterations: 1000,
298 };
299
300 let qtsne_config = QtSNEConfig {
301 n_components: 2,
302 perplexity: 20.0,
303 early_exaggeration: 12.0,
304 learning_rate: 200.0,
305 max_iterations: 500,
306 quantum_enhancement: QuantumEnhancementLevel::Light,
307 num_qubits: 4,
308 distance_metric: QuantumDistanceMetric::QuantumEuclidean,
309 random_state: Some(42),
310 };
311
312 let mut qpca_method = QuantumDimensionalityReducer::new(DimensionalityReductionAlgorithm::QPCA)
313 .with_qpca_config(qpca_config);
314 let mut qtsne_method =
315 QuantumDimensionalityReducer::new(DimensionalityReductionAlgorithm::QtSNE)
316 .with_qtsne_config(qtsne_config);
317
318 let methods = vec![("QPCA", qpca_method), ("Qt-SNE", qtsne_method)];
319
320 for (name, mut method) in methods {
321 println!("\nEvaluating {name}...");
322
323 method.fit(data)?;
324 let transformed = method.transform(data)?;
325
326 let metrics = DimensionalityReductionMetrics {
328 reconstruction_error: 0.05,
329 explained_variance_ratio: 0.85,
330 cumulative_explained_variance: 0.85,
331 trustworthiness: Some(0.90),
332 continuity: Some(0.88),
333 stress: Some(0.12),
334 silhouette_score: Some(0.75),
335 kl_divergence: Some(0.08),
336 cv_score: Some(0.82),
337 };
338
339 println!(
340 " Reconstruction Error: {:.6}",
341 metrics.reconstruction_error
342 );
343 println!(
344 " Explained Variance: {:.4}",
345 metrics.explained_variance_ratio
346 );
347 if let Some(trust) = metrics.trustworthiness {
348 println!(" Trustworthiness: {trust:.4}");
349 }
350 if let Some(cont) = metrics.continuity {
351 println!(" Continuity: {cont:.4}");
352 }
353
354 if let Some(silhouette) = metrics.silhouette_score {
355 println!(" Silhouette Score: {silhouette:.4}");
356 }
357
358 if let Some(stress) = metrics.stress {
359 println!(" Stress: {stress:.6}");
360 }
361
362 if let Some(kl_div) = metrics.kl_divergence {
363 println!(" KL Divergence: {kl_div:.6}");
364 }
365 }
366
367 Ok(())
368}
369
370fn demo_specialized_configs(data: &Array2<f64>) -> Result<()> {
372 println!("\n--- Specialized Configurations Demo ---");
373
374 println!("Specialized configuration types would include:");
376
377 println!(" - Time Series DR: window_size=10, overlap=5, temporal_regularization=0.1");
379
380 println!(" - Image/Tensor DR: patch_size=(4,4), stride=(2,2), spatial_regularization=0.05");
382
383 println!(" - Graph DR: graph_construction=knn, n_neighbors=10, edge_weights=distance");
385
386 println!(" - Streaming DR: batch_size=32, forgetting_factor=0.95, update_frequency=10");
388
389 println!(" - Graph DR with k-NN construction");
390 println!(" - Streaming DR with adaptive learning");
391 println!(" - Feature Selection with mutual information criterion");
392
393 println!("\nDefault configuration options:");
395 println!(" - Default QPCA config (2 components, VQE solver)");
396 println!(" - Default QICA config (2 components, logcosh nonlinearity)");
397 println!(" - Default Qt-SNE config (2 components, perplexity 30)");
398 println!(" - Default QAutoencoder config (standard VAE)");
399
400 Ok(())
401}
402
403fn generate_synthetic_data(
405 n_samples: usize,
406 n_features: usize,
407) -> Result<(Array2<f64>, Array1<i32>)> {
408 let mut data = Array2::zeros((n_samples, n_features));
409 let mut labels = Array1::zeros(n_samples);
410
411 let clusters = [
413 ([2.0, 2.0, 0.0], 0.5), ([0.0, -2.0, 1.0], 0.7), ([-2.0, 0.0, -1.0], 0.6), ];
417
418 for i in 0..n_samples {
419 let cluster_idx = i % 3;
420 let (center, std) = clusters[cluster_idx];
421 labels[i] = cluster_idx as i32;
422
423 for j in 0..n_features {
425 let base_value = if j < 3 { center[j] } else { 0.0 };
426 let noise = (fastrand::f64() - 0.5) * std * 2.0;
427 data[[i, j]] = base_value + noise;
428
429 if j > 2 {
431 data[[i, j]] += 0.3 * data[[i, j % 3]];
432 }
433 }
434 }
435
436 Ok((data, labels))
437}
438
439fn print_algorithm_info() {
441 println!("Available Quantum Dimensionality Reduction Algorithms:");
442 println!(" 1. QPCA - Quantum Principal Component Analysis");
443 println!(" 2. QICA - Quantum Independent Component Analysis");
444 println!(" 3. Qt-SNE - Quantum t-distributed Stochastic Neighbor Embedding");
445 println!(" 4. QUMAP - Quantum Uniform Manifold Approximation and Projection");
446 println!(" 5. QLDA - Quantum Linear Discriminant Analysis");
447 println!(" 6. QFactorAnalysis - Quantum Factor Analysis");
448 println!(" 7. QCCA - Quantum Canonical Correlation Analysis");
449 println!(" 8. QNMF - Quantum Non-negative Matrix Factorization");
450 println!(" 9. QVAE - Quantum Variational Autoencoder");
451 println!(" 10. QDenoisingAE - Quantum Denoising Autoencoder");
452 println!(" 11. QSparseAE - Quantum Sparse Autoencoder");
453 println!(" 12. QManifoldLearning - Quantum Manifold Learning");
454 println!(" 13. QKernelPCA - Quantum Kernel PCA");
455 println!(" 14. QMDS - Quantum Multidimensional Scaling");
456 println!(" 15. QIsomap - Quantum Isomap");
457 println!(" 16. Feature Selection Methods (Mutual Info, RFE, LASSO, Ridge, Variance)");
458 println!(" 17. Specialized Methods (Time Series, Image/Tensor, Graph, Streaming)");
459 println!();
460}
461
462#[cfg(test)]
463mod tests {
464 use super::*;
465
466 #[test]
467 fn test_synthetic_data_generation() {
468 let (data, labels) = generate_synthetic_data(50, 5).unwrap();
469 assert_eq!(data.nrows(), 50);
470 assert_eq!(data.ncols(), 5);
471 assert_eq!(labels.len(), 50);
472
473 let unique_labels: std::collections::HashSet<_> = labels.iter().cloned().collect();
475 assert_eq!(unique_labels.len(), 3);
476 }
477
478 #[test]
479 fn test_qpca_demo() {
480 let (data, _) = generate_synthetic_data(30, 5).unwrap();
481 assert!(demo_qpca(&data).is_ok());
482 }
483
484 #[test]
485 fn test_qica_demo() {
486 let (data, _) = generate_synthetic_data(30, 5).unwrap();
487 assert!(demo_qica(&data).is_ok());
488 }
489
490 #[test]
491 fn test_default_configs() {
492 let _qpca_config = create_default_qpca_config();
493 let _qica_config = create_default_qica_config();
494 let _qtsne_config = create_default_qtsne_config();
495 let _qautoencoder_config = create_default_qautoencoder_config();
496
497 assert!(true);
499 }
500}
501
502const fn create_default_qpca_config() -> QPCAConfig {
504 QPCAConfig {
505 n_components: 2,
506 eigensolver: QuantumEigensolver::VQE,
507 quantum_enhancement: QuantumEnhancementLevel::Light,
508 num_qubits: 4,
509 whiten: false,
510 random_state: Some(42),
511 tolerance: 1e-6,
512 max_iterations: 100,
513 }
514}
515
516fn create_default_qica_config() -> QICAConfig {
517 QICAConfig {
518 n_components: 2,
519 max_iterations: 100,
520 tolerance: 1e-4,
521 quantum_enhancement: QuantumEnhancementLevel::Light,
522 num_qubits: 4,
523 learning_rate: 1.0,
524 nonlinearity: "logcosh".to_string(),
525 random_state: Some(42),
526 }
527}
528
529const fn create_default_qtsne_config() -> QtSNEConfig {
530 QtSNEConfig {
531 n_components: 2,
532 perplexity: 30.0,
533 early_exaggeration: 12.0,
534 learning_rate: 200.0,
535 max_iterations: 100,
536 quantum_enhancement: QuantumEnhancementLevel::Light,
537 num_qubits: 4,
538 distance_metric: QuantumDistanceMetric::QuantumEuclidean,
539 random_state: Some(42),
540 }
541}
542
543fn create_default_qautoencoder_config() -> QAutoencoderConfig {
544 QAutoencoderConfig {
545 encoder_layers: vec![4, 2],
546 decoder_layers: vec![2, 4],
547 latent_dim: 2,
548 architecture: AutoencoderArchitecture::Standard,
549 learning_rate: 0.001,
550 epochs: 10,
551 batch_size: 16,
552 quantum_enhancement: QuantumEnhancementLevel::Light,
553 num_qubits: 4,
554 beta: 1.0,
555 noise_level: 0.1,
556 sparsity_parameter: 0.01,
557 random_state: Some(42),
558 }
559}